perf: memoize parseImageIds, fix checkLimit OR query, loading skeletons, dashboard cache, compound indexes, sidebar active state, matches notified fix, padding fixes, match criteria in property detail

This commit is contained in:
egecankomur
2026-05-13 13:08:05 +03:00
parent 933cb17107
commit 7c677dfa4b
34 changed files with 1257 additions and 308 deletions
+13 -3
View File
@@ -10,6 +10,7 @@ import {
TABLES,
type Property,
type PropertyMatch,
type CustomerSearch,
type Activity,
} from "@/lib/appwrite/schema";
import { createAdminClient } from "@/lib/appwrite/server";
@@ -35,7 +36,7 @@ export default async function PropertyDetailPage({ params }: Props) {
if (property.tenantId !== ctx.tenantId) notFound();
const [customers, matchesResult, activitiesResult] = await Promise.all([
const [customers, matchesResult, activitiesResult, searchesResult] = await Promise.all([
listCustomers(ctx.tenantId),
tablesDB.listRows({
databaseId: DATABASE_ID,
@@ -57,11 +58,19 @@ export default async function PropertyDetailPage({ params }: Props) {
Query.limit(20),
],
}),
tablesDB.listRows({
databaseId: DATABASE_ID,
tableId: TABLES.customerSearches,
queries: [
Query.equal("tenantId", ctx.tenantId),
Query.limit(200),
],
}),
]);
const matches = JSON.parse(JSON.stringify(matchesResult.rows)) as PropertyMatch[];
const activities = JSON.parse(JSON.stringify(activitiesResult.rows)) as Activity[];
const customerMap = Object.fromEntries(customers.map((c) => [c.$id, c.name]));
const searches = JSON.parse(JSON.stringify(searchesResult.rows)) as CustomerSearch[];
const imageIds = parseImageIds(property.imageIds);
return (
@@ -70,7 +79,8 @@ export default async function PropertyDetailPage({ params }: Props) {
matches={matches}
activities={activities}
imageIds={imageIds}
customerMap={customerMap}
customers={customers}
searches={searches}
/>
);
}
@@ -0,0 +1,44 @@
import { Skeleton } from "@/components/ui/skeleton";
export default function PropertiesLoading() {
return (
<div className="flex flex-1 flex-col gap-4 p-4 md:p-6">
{/* Başlık + buton */}
<div className="flex items-center justify-between">
<div className="space-y-1">
<Skeleton className="h-7 w-24" />
<Skeleton className="h-4 w-40" />
</div>
<Skeleton className="h-9 w-28 rounded-md" />
</div>
{/* Filtre bar */}
<div className="flex gap-2 flex-wrap">
<Skeleton className="h-9 w-48 rounded-md" />
<Skeleton className="h-9 w-32 rounded-md" />
<Skeleton className="h-9 w-32 rounded-md" />
</div>
{/* Tablo */}
<div className="rounded-xl border overflow-hidden">
<div className="bg-muted/30 p-3 flex gap-4">
{[120, 80, 80, 70, 60].map((w, i) => (
<Skeleton key={i} className="h-3" style={{ width: w }} />
))}
</div>
{Array.from({ length: 8 }).map((_, i) => (
<div key={i} className="border-t p-3 flex gap-4 items-center">
<Skeleton className="h-10 w-10 rounded-md shrink-0" />
<div className="flex-1 space-y-1.5">
<Skeleton className="h-4 w-48" />
<Skeleton className="h-3 w-32" />
</div>
<Skeleton className="h-4 w-20 hidden sm:block" />
<Skeleton className="h-4 w-16 hidden md:block" />
<Skeleton className="h-5 w-16 rounded-full" />
</div>
))}
</div>
</div>
);
}