diff --git a/src/app/layout.tsx b/src/app/layout.tsx index ddd934b..295a773 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -11,6 +11,7 @@ import { ModeToggle } from "~/components/mode-toggle"; import { Login } from "~/components/login"; import { type Session } from "next-auth"; import { getServerAuthSession } from "~/server/auth"; +import ButtonSkeleton from "~/components/loading/button-loader"; const inter = Inter({ subsets: ["latin"], @@ -50,7 +51,7 @@ export default async function RootLayout({
{session && ( - Loading...
}> + }> )} diff --git a/src/app/loading.tsx b/src/app/loading.tsx deleted file mode 100644 index 8e3e3db..0000000 --- a/src/app/loading.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { Skeleton } from "~/components/ui/skeleton"; -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "~/components/ui/table"; -import { idToTextMap } from "~/utils/optionMapping"; - -export default function SkeletonDemo() { - const answerOptions = [ - { id: 0, option: "Strongly Disagree" }, - { id: 1, option: "Disagree" }, - { id: 2, option: "Neutral" }, - { id: 3, option: "Agree" }, - { id: 4, option: "Strongly Agree" }, - ]; - - // create 20 dummy questions - const filteredQuestions = Array.from({ length: 20 }, (_, i) => ({ - id: i.toString(), - questionText: `Question ${i + 1}`, - })); - - return ( -
-
- - - - Question - {answerOptions.map((option) => ( - {idToTextMap[option.id]} - ))} - - - - {filteredQuestions?.map((question) => ( - - - - - {answerOptions.map((option) => ( - - - - ))} - - ))} - -
-
-
- ); -} diff --git a/src/app/page.tsx b/src/app/page.tsx index e9bd239..d1d00a3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -5,11 +5,11 @@ import SelectRole from "../components/select-role"; import React, { Suspense } from "react"; import { type Session } from "next-auth"; import { db } from "~/server/db"; +import RoleSelectionSkeleton from "~/components/loading/role-selection-loader"; const Home: React.FC = async () => { const session = await getServerAuthSession(); - // Use Suspense to suspend rendering while the data is being fetched return (
@@ -44,7 +44,7 @@ const Home: React.FC = async () => { {/* If the user is logged in, show the SelectRole component */} {session && (
- Loading...
}> + }>
diff --git a/src/app/result/[role]/page.tsx b/src/app/result/[role]/page.tsx index 38731c2..45d7e92 100644 --- a/src/app/result/[role]/page.tsx +++ b/src/app/result/[role]/page.tsx @@ -14,6 +14,8 @@ import { slugify } from "~/utils/slugify"; import ResultsWrapper from "~/components/results"; import { type Metadata } from "next"; +import ButtonSkeleton from "~/components/loading/button-loader"; +import LegendSkeleton from "~/components/loading/results-loader"; export const metadata: Metadata = { title: "Results", @@ -30,11 +32,11 @@ const Results: React.FC = async () => { Tech Survey - Results - Loading...
}> + }> - Loading...}> + }> {!session && ( diff --git a/src/app/survey/[role]/page.tsx b/src/app/survey/[role]/page.tsx index 0403b53..eeb657e 100644 --- a/src/app/survey/[role]/page.tsx +++ b/src/app/survey/[role]/page.tsx @@ -2,7 +2,7 @@ import { getServerAuthSession } from "~/server/auth"; import { type AnswerOption, type Question } from "~/models/types"; import { Suspense } from "react"; import { SurveyQuestionnaire } from "~/components/survey-questionnaire"; -import Loading from "~/app/loading"; +import SurveyQuestionLoader from "~/components/loading/survey-question-loader"; import { db } from "~/server/db"; import { type Metadata } from "next"; @@ -12,7 +12,7 @@ export const metadata: Metadata = { }; const SuspenseSurveyData = () => ( - }> + }> ); diff --git a/src/app/thank-you/page.tsx b/src/app/thank-you/page.tsx index 6eed521..1449353 100644 --- a/src/app/thank-you/page.tsx +++ b/src/app/thank-you/page.tsx @@ -9,6 +9,7 @@ import { } from "~/models/types"; import { type Metadata } from "next"; +import ButtonSkeleton from "~/components/loading/button-loader"; export const metadata: Metadata = { title: "Thank You", @@ -88,7 +89,7 @@ const ThankYou = async () => { We appreciate your time and effort in completing the survey.

- Loading...
}> + }> { + return ( + + ); +}; + +export default ButtonSkeleton; diff --git a/src/components/loading/progression-bar-loader.tsx b/src/components/loading/progression-bar-loader.tsx new file mode 100644 index 0000000..90e5209 --- /dev/null +++ b/src/components/loading/progression-bar-loader.tsx @@ -0,0 +1,49 @@ +import { Fragment } from "react"; +import { type Role } from "~/models/types"; + +const NavigationSkeleton = ({ roles }: { roles: Role[] }) => { + return ( + + ); +}; + +export default NavigationSkeleton; diff --git a/src/components/loading/results-loader.tsx b/src/components/loading/results-loader.tsx new file mode 100644 index 0000000..7226a85 --- /dev/null +++ b/src/components/loading/results-loader.tsx @@ -0,0 +1,41 @@ +"use client"; + +import { ResponsiveContainer } from "recharts"; + +const LegendSkeleton = () => { + return ( +
+

Legend

+
+ {[...Array(5)].map((_, index) => ( +
+
+ +
+ ))} +
+ {[...Array(3)].map((_, index) => ( +
+
+

Question

+
+ +
+
+
+
+
+

Question

+
+ +
+
+
+
+
+ ))} +
+ ); +}; + +export default LegendSkeleton; diff --git a/src/components/loading/role-selection-loader.tsx b/src/components/loading/role-selection-loader.tsx new file mode 100644 index 0000000..57c81c8 --- /dev/null +++ b/src/components/loading/role-selection-loader.tsx @@ -0,0 +1,27 @@ +import ButtonSkeleton from "./button-loader"; + +const RoleSelectionSkeleton = () => { + return ( +
+

Select Roles

+
    + {Array.from({ length: 15 }).map((_, index) => ( +
  • +
    +
    +
    +
    +
  • + ))} +
+
+ +
+
+ ); +}; + +export default RoleSelectionSkeleton; diff --git a/src/components/loading/survey-question-loader.tsx b/src/components/loading/survey-question-loader.tsx new file mode 100644 index 0000000..cb9bba2 --- /dev/null +++ b/src/components/loading/survey-question-loader.tsx @@ -0,0 +1,59 @@ +import { Skeleton } from "~/components/ui/skeleton"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "~/components/ui/table"; +import NavigationSkeleton from "./progression-bar-loader"; + +export default function SurveyQuestionLoader() { + const answerOptions = [{ id: 0 }, { id: 1 }, { id: 2 }, { id: 3 }]; + + // create 6 roles of type Role[] + const roles = Array.from({ length: 6 }, (_, index) => ({ + id: index.toString(), + role: `Role ${index}`, + default: index === 0, + })); + + return ( +
+ +
+
+ + + + + + + {answerOptions.map((option) => ( + + + + ))} + + + + {Array.from({ length: 20 }).map((_, index) => ( + + + + + {answerOptions.map((option) => ( + + + + ))} + + ))} + +
+
+
+
+ ); +} diff --git a/src/components/results.tsx b/src/components/results.tsx index e3b46cd..f717d76 100644 --- a/src/components/results.tsx +++ b/src/components/results.tsx @@ -2,6 +2,7 @@ import { type TransformedData } from "~/models/types"; import ShowResults from "./show-results"; +import { idToTextMap } from "~/utils/optionMapping"; export default function ResultsWrapper({ data }: { data: TransformedData }) { return ( @@ -51,11 +52,13 @@ export function ResultCommons({ data }: { data: TransformedData }) { style={customTooltipStyle} >

- {payload.map((entry, index) => ( - - {`${entry.name} : ${entry.value}`} - - ))} + {payload.map( + (entry: { name: string; value: number }, index: number) => ( + + {`${idToTextMap[+entry.name]} : ${entry.value}`} + + ), + )}

diff --git a/src/components/show-results.tsx b/src/components/show-results.tsx index 182efbd..a981797 100644 --- a/src/components/show-results.tsx +++ b/src/components/show-results.tsx @@ -13,6 +13,7 @@ import { import { type TransformedData } from "~/models/types"; import { slugify } from "~/utils/slugify"; import { ResultCommons } from "./results"; +import { idToTextMap } from "~/utils/optionMapping"; const ShowResults = ({ data }: { data: TransformedData }) => { const pathname = usePathname() || ""; @@ -30,6 +31,13 @@ const ShowResults = ({ data }: { data: TransformedData }) => { data, }); + // sort the uniqueDataKeys based on the order of the dataKeys + uniqueDataKeys.sort((a, b) => { + const aIndex = Object.keys(idToTextMap).indexOf(a); + const bIndex = Object.keys(idToTextMap).indexOf(b); + return aIndex - bIndex; + }); + return (

Legend

@@ -40,7 +48,7 @@ const ShowResults = ({ data }: { data: TransformedData }) => { className="mr-2 h-4 w-4 rounded-full" style={{ backgroundColor: dataKeyColors[dataKey] }} >
- {dataKey} + {idToTextMap[+dataKey]} ))}