--- import DashboardLayout from '../../../../layouts/DashboardLayout.astro'; import { Icon } from 'astro-icon/components'; import { db } from '../../../../db'; import { clients, timeEntries, members, categories, users } from '../../../../db/schema'; import { eq, and, desc, sql } from 'drizzle-orm'; import { formatTimeRange } from '../../../../lib/formatTime'; const user = Astro.locals.user; if (!user) return Astro.redirect('/login'); const { id } = Astro.params; if (!id) return Astro.redirect('/dashboard/clients'); // Get current team from cookie const currentTeamId = Astro.cookies.get('currentTeamId')?.value; const userMemberships = await db.select() .from(members) .where(eq(members.userId, user.id)) .all(); if (userMemberships.length === 0) return Astro.redirect('/dashboard'); // Use current team or fallback to first membership const userMembership = currentTeamId ? userMemberships.find(m => m.organizationId === currentTeamId) || userMemberships[0] : userMemberships[0]; const client = await db.select() .from(clients) .where(and( eq(clients.id, id), eq(clients.organizationId, userMembership.organizationId) )) .get(); if (!client) return Astro.redirect('/dashboard/clients'); // Get recent activity const recentEntries = await db.select({ entry: timeEntries, category: categories, user: users, }) .from(timeEntries) .leftJoin(categories, eq(timeEntries.categoryId, categories.id)) .leftJoin(users, eq(timeEntries.userId, users.id)) .where(eq(timeEntries.clientId, client.id)) .orderBy(desc(timeEntries.startTime)) .limit(10) .all(); // Calculate total time tracked const totalTimeResult = await db.select({ totalDuration: sql`sum(CASE WHEN ${timeEntries.endTime} IS NOT NULL THEN ${timeEntries.endTime} - ${timeEntries.startTime} ELSE 0 END)` }) .from(timeEntries) .where(eq(timeEntries.clientId, client.id)) .get(); const totalDurationMs = totalTimeResult?.totalDuration || 0; const totalHours = Math.floor(totalDurationMs / (1000 * 60 * 60)); const totalMinutes = Math.floor((totalDurationMs % (1000 * 60 * 60)) / (1000 * 60)); // Get total entries count const totalEntriesResult = await db.select({ count: sql`count(*)` }) .from(timeEntries) .where(eq(timeEntries.clientId, client.id)) .get(); const totalEntriesCount = totalEntriesResult?.count || 0; ---

{client.name}

{client.name}

{client.email && ( )} {client.phone && ( )} {(client.street || client.city || client.state || client.zip || client.country) && (
{client.street &&
{client.street}
} {(client.city || client.state || client.zip) && (
{[client.city, client.state, client.zip].filter(Boolean).join(', ')}
)} {client.country &&
{client.country}
}
)}
Edit
Total Time Tracked
{totalHours}h {totalMinutes}m
Across all projects
Total Entries
{totalEntriesCount}
Recorded entries

Information

Created
{client.createdAt?.toLocaleDateString() ?? 'N/A'}

Recent Activity

{recentEntries.length > 0 ? (
{recentEntries.map(({ entry, category, user: entryUser }) => ( ))}
Description Category User Date Duration
{entry.description || '-'} {category ? (
{category.name}
) : '-'}
{entryUser?.name || 'Unknown'} {entry.startTime.toLocaleDateString()} {formatTimeRange(entry.startTime, entry.endTime)}
) : (
No time entries recorded for this client yet.
)} {recentEntries.length > 0 && ( )}