attendace, user stats
This commit is contained in:
parent
d6a77fcd23
commit
3e30fae173
Binary file not shown.
@ -80,7 +80,8 @@ export async function GET(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get recent activity (attendance in last 30 days)
|
// Get recent activity (attendance in last 30 days)
|
||||||
const thirtyDaysAgo = Date.now() - 30 * 24 * 60 * 60 * 1000;
|
// Database stores timestamps in seconds, so convert milliseconds to seconds
|
||||||
|
const thirtyDaysAgo = Math.floor(Date.now() / 1000) - 30 * 24 * 60 * 60;
|
||||||
const attendanceResult = (await db.all(
|
const attendanceResult = (await db.all(
|
||||||
sql`SELECT COUNT(*) as count FROM attendance
|
sql`SELECT COUNT(*) as count FROM attendance
|
||||||
WHERE user_id IN (SELECT id FROM users WHERE gym_id = ${gymId})
|
WHERE user_id IN (SELECT id FROM users WHERE gym_id = ${gymId})
|
||||||
|
|||||||
@ -69,16 +69,16 @@ export default function AttendancePage() {
|
|||||||
{record.type}
|
{record.type}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-3 px-4 text-sm text-muted-foreground">
|
<td className="py-3 px-4 text-sm text-muted-foreground">
|
||||||
{new Date(record.checkIn).toLocaleString()}
|
{new Date(record.checkInTime).toLocaleString()}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-3 px-4 text-sm text-muted-foreground">
|
<td className="py-3 px-4 text-sm text-muted-foreground">
|
||||||
{record.checkOut
|
{record.checkOutTime
|
||||||
? new Date(record.checkOut).toLocaleString()
|
? new Date(record.checkOutTime).toLocaleString()
|
||||||
: "-"}
|
: "-"}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-3 px-4">
|
<td className="py-3 px-4">
|
||||||
<Badge variant={record.checkOut ? "gray" : "success"}>
|
<Badge variant={record.checkOutTime ? "gray" : "success"}>
|
||||||
{record.checkOut ? "Completed" : "Active"}
|
{record.checkOutTime ? "Completed" : "Active"}
|
||||||
</Badge>
|
</Badge>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -260,7 +260,7 @@ export function UserGrid({
|
|||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
headerName: "Last Visit",
|
headerName: "Last Visit",
|
||||||
valueGetter: (params) => params.data?.client?.lastVisit,
|
valueGetter: (params) => params.data?.lastCheckInTime,
|
||||||
filter: "agDateColumnFilter",
|
filter: "agDateColumnFilter",
|
||||||
sortable: true,
|
sortable: true,
|
||||||
valueFormatter: (params: any) =>
|
valueFormatter: (params: any) =>
|
||||||
|
|||||||
@ -587,9 +587,9 @@ export function UserManagement({ gymId }: UserManagementProps) {
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Last Visit:</span>{" "}
|
<span className="font-medium">Last Visit:</span>{" "}
|
||||||
{selectedUser.client.lastVisit
|
{selectedUser.lastCheckInTime
|
||||||
? new Date(
|
? new Date(
|
||||||
selectedUser.client.lastVisit,
|
selectedUser.lastCheckInTime,
|
||||||
).toLocaleDateString()
|
).toLocaleDateString()
|
||||||
: "Never"}
|
: "Never"}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -55,8 +55,8 @@ export interface Gym {
|
|||||||
export interface AttendanceRecord {
|
export interface AttendanceRecord {
|
||||||
id: string;
|
id: string;
|
||||||
userId: string;
|
userId: string;
|
||||||
checkIn: string;
|
checkInTime: Date;
|
||||||
checkOut?: string;
|
checkOutTime?: Date;
|
||||||
date: string;
|
date: string;
|
||||||
type?: string;
|
type?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1318,9 +1318,14 @@ export class DrizzleDatabase implements IDatabase {
|
|||||||
membershipStatus: String(
|
membershipStatus: String(
|
||||||
row.membershipStatus,
|
row.membershipStatus,
|
||||||
) as Client["membershipStatus"],
|
) as Client["membershipStatus"],
|
||||||
joinDate: new Date(row.joinDate as number | Date),
|
joinDate:
|
||||||
|
typeof row.joinDate === "number"
|
||||||
|
? new Date(row.joinDate * 1000)
|
||||||
|
: new Date(row.joinDate as Date),
|
||||||
lastVisit: row.lastVisit
|
lastVisit: row.lastVisit
|
||||||
? new Date(row.lastVisit as number | Date)
|
? typeof row.lastVisit === "number"
|
||||||
|
? new Date(row.lastVisit * 1000)
|
||||||
|
: new Date(row.lastVisit as Date)
|
||||||
: undefined,
|
: undefined,
|
||||||
emergencyContact: row.emergencyContactName
|
emergencyContact: row.emergencyContactName
|
||||||
? {
|
? {
|
||||||
@ -1363,12 +1368,20 @@ export class DrizzleDatabase implements IDatabase {
|
|||||||
id: String(row.id),
|
id: String(row.id),
|
||||||
userId: String(row.userId),
|
userId: String(row.userId),
|
||||||
type: String(row.type) as Attendance["type"],
|
type: String(row.type) as Attendance["type"],
|
||||||
checkInTime: new Date(row.checkInTime as number | Date),
|
checkInTime:
|
||||||
|
typeof row.checkInTime === "number"
|
||||||
|
? new Date(row.checkInTime * 1000)
|
||||||
|
: new Date(row.checkInTime as Date),
|
||||||
checkOutTime: row.checkOutTime
|
checkOutTime: row.checkOutTime
|
||||||
? new Date(row.checkOutTime as number | Date)
|
? typeof row.checkOutTime === "number"
|
||||||
|
? new Date(row.checkOutTime * 1000)
|
||||||
|
: new Date(row.checkOutTime as Date)
|
||||||
: undefined,
|
: undefined,
|
||||||
notes: row.notes ? String(row.notes) : undefined,
|
notes: row.notes ? String(row.notes) : undefined,
|
||||||
createdAt: new Date(row.createdAt as number | Date),
|
createdAt:
|
||||||
|
typeof row.createdAt === "number"
|
||||||
|
? new Date(row.createdAt * 1000)
|
||||||
|
: new Date(row.createdAt as Date),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user