diff --git a/app/(main)/account/page.tsx b/app/(main)/account/page.tsx
index e3d00ef..53156d0 100644
--- a/app/(main)/account/page.tsx
+++ b/app/(main)/account/page.tsx
@@ -1,8 +1,8 @@
import {
BentoContainer,
BentoContainerHeader,
-} from "@/components/bento-container";
-import { Title, Description, SubTitle } from "@/components/texts";
+} from "@/components/reusables/bento-container";
+import { Title, Description, SubTitle } from "@/components/reusables/texts";
import AccountField from "@/components/account/account-field";
import { Button } from "@/components/ui/button";
import { LogOut } from "lucide-react";
diff --git a/app/(main)/day/[date]/loading.tsx b/app/(main)/day/[date]/loading.tsx
index 23591f2..22ddb7d 100644
--- a/app/(main)/day/[date]/loading.tsx
+++ b/app/(main)/day/[date]/loading.tsx
@@ -1,9 +1,14 @@
+import { Skeleton } from "@/components/ui/skeleton";
+
const Loading = () => {
return (
-
- Loading...
+
+
+
+
+
- )
+ );
};
-export default Loading;
\ No newline at end of file
+export default Loading;
diff --git a/app/(main)/day/[date]/page.tsx b/app/(main)/day/[date]/page.tsx
index d0a9538..b0a125f 100644
--- a/app/(main)/day/[date]/page.tsx
+++ b/app/(main)/day/[date]/page.tsx
@@ -1,6 +1,4 @@
-import { Suspense } from "react";
import AttendanceTableServer from "@/components/attendance-table/attendance-table-server";
-import Loader from "@/components/loader";
interface SingleDayPageProps {
// When a page component is async, Next.js may provide params as a thenable.
@@ -11,19 +9,9 @@ const SingleDayPage = async ({ params }: SingleDayPageProps) => {
return (
);
};
-export default SingleDayPage;
+export default SingleDayPage;
\ No newline at end of file
diff --git a/app/(main)/day/range/loading.tsx b/app/(main)/day/range/loading.tsx
deleted file mode 100644
index 23591f2..0000000
--- a/app/(main)/day/range/loading.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-const Loading = () => {
- return (
-
- Loading...
-
- )
-};
-
-export default Loading;
\ No newline at end of file
diff --git a/app/(main)/error.tsx b/app/(main)/error.tsx
new file mode 100644
index 0000000..6f6c537
--- /dev/null
+++ b/app/(main)/error.tsx
@@ -0,0 +1,10 @@
+"use client";
+
+import { ErrorBoundaryProps } from "@/lib/error-types";
+import FetchFailed from "@/components/error/fetch-failed";
+
+const ErrorPage: React.FC
= ({ error, reset }) => {
+ return ;
+};
+
+export default ErrorPage;
\ No newline at end of file
diff --git a/app/(main)/home/loading.tsx b/app/(main)/home/loading.tsx
deleted file mode 100644
index 71fed28..0000000
--- a/app/(main)/home/loading.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-const LoadingHomePage = () => {
- return (
-
- loading...
-
- )
-};
-
-export default LoadingHomePage;
\ No newline at end of file
diff --git a/app/(main)/home/page.tsx b/app/(main)/home/page.tsx
index 7c95ea2..4ce5ba2 100644
--- a/app/(main)/home/page.tsx
+++ b/app/(main)/home/page.tsx
@@ -3,8 +3,8 @@
import {
BentoContainer,
BentoContainerHeader,
-} from "@/components/bento-container";
-import { Description, Title } from "@/components/texts";
+} from "@/components/reusables/bento-container";
+import { Description, Title } from "@/components/reusables/texts";
import { useDates } from "@/context/dates-context";
import {
DayCards,
@@ -13,11 +13,15 @@ import {
} from "@/components/days/day-cards";
import { groupDatesByMonth } from "@/lib/utils";
import { ScrollArea } from "@/components/ui/scroll-area";
-import AlertMessage from "@/components/alert-message";
+import AlertMessage from "@/components/reusables/alert-message";
+import { Skeleton } from "@/components/ui/skeleton";
const HomePage = () => {
const { dates } = useDates();
- const groupedDates = groupDatesByMonth(dates);
+ const groupedDates = dates ? groupDatesByMonth(dates) : {};
+
+ const isLoading = dates === null;
+ const isEmpty = dates && dates.length === 0;
return (
@@ -30,20 +34,45 @@ const HomePage = () => {
-
-
- {Object.entries(groupedDates).map(([monthYear, days]) => (
-
-
- {days.map((item) => (
-
- ))}
-
-
- ))}
+ {isLoading && (
+
+ {Array.from({ length: 2 }).map((_, monthIndex) => (
+
+
+
+ {Array.from({ length: 4 }).map(
+ (_, dayIndex) => (
+
+ )
+ )}
+
+
+ ))}
+
+ )}
+
+ {isEmpty && (
+
+ )}
+
+ {!isLoading &&
+ !isEmpty &&
+ Object.entries(groupedDates).map(([monthYear, days]) => (
+
+
+ {days.map((item) => (
+
+ ))}
+
+
+ ))}
);
};
-export default HomePage;
+
+export default HomePage;
\ No newline at end of file
diff --git a/app/(main)/layout.tsx b/app/(main)/layout.tsx
index 4239760..f99756e 100644
--- a/app/(main)/layout.tsx
+++ b/app/(main)/layout.tsx
@@ -1,33 +1,41 @@
import { LoadingProvider } from "@/context/loading-context";
+import { SidebarOpenProvider } from "@/context/sidebar-open-context";
+import { DatesProvider } from "@/context/dates-context";
import Header from "@/components/header";
-import { Toaster } from "sonner";
-import React from "react";
import DaysSidebarServer from "@/components/days/days-sidebar-server";
+import { Toaster } from "sonner";
import NextTopLoader from "nextjs-toploader";
-import { DatesProvider } from "@/context/dates-context";
+import React, { Suspense } from "react";
+import DaysSidebarLoader from "@/components/days/days-sidebar-loader";
export const dynamic = "force-dynamic";
interface MainLayoutProps {
children: React.ReactNode;
}
+
const MainLayout: React.FC = ({ children }) => {
return (
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ }>
+
+
+
+
+
-
-
-
+
+
+
);
};
diff --git a/app/(main)/student/[studentId]/loading.tsx b/app/(main)/student/[studentId]/loading.tsx
deleted file mode 100644
index fb0e670..0000000
--- a/app/(main)/student/[studentId]/loading.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import Loader from "@/components/loader";
-
-const LoadingHomePage = () => {
- return (
-
-
-
- );
-};
-
-export default LoadingHomePage;
diff --git a/app/(main)/student/[studentId]/page.tsx b/app/(main)/student/[studentId]/page.tsx
index 4278d9a..85a35a8 100644
--- a/app/(main)/student/[studentId]/page.tsx
+++ b/app/(main)/student/[studentId]/page.tsx
@@ -1,22 +1,4 @@
-import { AttendanceRecordResponse } from "@/lib/types";
-import {
- fetchJSON,
- formatDateForRender,
- formatTimeForRender,
-} from "@/lib/utils";
-
-import {
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableHeader,
- TableRow,
-} from "@/components/ui/table";
-import { BentoContainer } from "@/components/bento-container";
-import { Description, SubTitle, Title } from "@/components/texts";
-import { ScrollArea } from "@/components/ui/scroll-area";
-import NoDataMessage from "@/components/no-data-message";
+import StudentOnDate from "@/components/student/student-on-date";
interface StudentOnDatePageProps {
// params of the studentId
@@ -32,96 +14,7 @@ const StudentOnDatePage: React.FC = async ({
const studentId = (await params).studentId;
const date = (await searchParams).date;
- const route =
- process.env.NEXT_PUBLIC_BASE_URL +
- `/api/reports/student/${studentId}?date=${date}`;
-
- const data = await fetchJSON(route);
-
- if (!data.success) return
-
- const student = [
- {
- label: "Partner Id",
- value:
- data.data.length > 0 ? data.data[0].partner_id : "Unknown ID",
- },
- {
- label: "Email",
- value:
- data.data.length > 0
- ? data.data[0].email_address
- : "Unknown Email",
- },
- {
- label: "Section",
- value:
- data.data.length > 0
- ? data.data[0].department
- : "Unknown Section",
- },
- ];
-
- // Format the data.data to just the checkIn and check_out fields
- const formattedData = data.data.map((item) => {
- return {
- checkIn: item.checkIn,
- check_out: item.check_out,
- };
- });
-
- return (
-
-
-
- Student Record for {studentId} on{" "}
- {formatDateForRender(date)}
-
-
- If data is missing, it means the student did not check in or out
- on that date. Refresh the page if you believe this is an error.
-
-
-
- {/* STUDENT PROFILE */}
-
- {student.map(({ value, label }) => (
-
- {value}
- {label}
-
- ))}
-
-
-
-
-
-
-
- Check In
- Check Out
-
-
-
- {formattedData.map((item, index) => (
-
-
- {formatTimeForRender(item.checkIn)}
-
-
- {formatTimeForRender(item.check_out)}
-
-
- ))}
-
-
-
-
-
- );
+ return ;
};
export default StudentOnDatePage;
diff --git a/app/error.tsx b/app/error.tsx
new file mode 100644
index 0000000..2352b72
--- /dev/null
+++ b/app/error.tsx
@@ -0,0 +1,10 @@
+"use client";
+
+import { ErrorBoundaryProps } from "@/lib/error-types";
+import FetchFailed from "@/components/error/fetch-failed";
+
+const ErrorPage: React.FC = ({ error, reset }) => {
+ return ;
+};
+
+export default ErrorPage;
diff --git a/app/layout.tsx b/app/layout.tsx
index fde59c6..698db8f 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -4,6 +4,7 @@ import "./globals.css";
import { Toaster } from "sonner";
import { LoadingProvider } from "@/context/loading-context";
import NextTopLoader from "nextjs-toploader";
+import ContentTransition from "../components/content-transition";
const geistSans = Geist({
variable: "--font-geist-sans",
@@ -30,9 +31,11 @@ export default function RootLayout({
-
- {children}
-
+
+
+ {children}
+
+