Skip to content

Commit c579a94

Browse files
committed
Add user page and interview table
1 parent e33d7a6 commit c579a94

File tree

6 files changed

+340
-0
lines changed

6 files changed

+340
-0
lines changed

frontend/peerprep/app/app.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
@import "tailwindcss";
2+
3+
@theme {
4+
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif,
5+
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
6+
}
7+
8+
html,
9+
body {
10+
11+
@media (prefers-color-scheme: dark) {
12+
color-scheme: dark;
13+
}
14+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.cell {
2+
width: 150px;
3+
text-align: right;
4+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Button, Card, Divider, Table, Text, Pagination, Group } from "@mantine/core";
2+
import classes from "./table.module.css";
3+
4+
export default function HistoryTable({ data }: { data: any[] }) {
5+
const rows = data.map((row, index) => (
6+
<Table.Tr key={row.name}>
7+
<Table.Td>{row.question}</Table.Td>
8+
<Table.Td ta="right">{row.completionDate}</Table.Td>
9+
<Table.Td ta="right">{row.difficulty}</Table.Td>
10+
<Table.Td ta="right">{row.topic}</Table.Td>
11+
<Table.Td ta="right">{row.language}</Table.Td>
12+
<Table.Td ta="right" style={{ width: 100 }}>
13+
<Button>View</Button>
14+
</Table.Td>
15+
</Table.Tr>
16+
));
17+
return (
18+
<Card shadow="sm" padding="lg">
19+
<Text fw={1000} size="xl" c="white" mb={"xs"}>
20+
Interviews
21+
</Text>
22+
<Divider />
23+
<Table.ScrollContainer minWidth={500}>
24+
<Table c={"white"} highlightOnHover>
25+
<Table.Thead>
26+
<Table.Tr>
27+
<Table.Th>Question</Table.Th>
28+
<Table.Th className={classes.cell}>Completion Date</Table.Th>
29+
<Table.Th className={classes.cell}>Difficulty</Table.Th>
30+
<Table.Th className={classes.cell}>Topic</Table.Th>
31+
<Table.Th className={classes.cell}>Language</Table.Th>
32+
<Table.Th className={classes.cell}></Table.Th>
33+
</Table.Tr>
34+
</Table.Thead>
35+
<Table.Tbody>{rows}</Table.Tbody>
36+
</Table>
37+
</Table.ScrollContainer>
38+
<Group justify="center">
39+
<Pagination total={5} siblings={3} defaultValue={1} />
40+
41+
</Group>
42+
</Card>
43+
);
44+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import {
2+
Grid,
3+
TextInput,
4+
Button,
5+
PasswordInput,
6+
Divider,
7+
Text,
8+
Image,
9+
useMantineTheme,
10+
Card,
11+
} from "@mantine/core";
12+
13+
import { Link } from "react-router";
14+
import Header from "../components/header/header";
15+
import logo from "../assets/images/logo.svg";
16+
import StatsCard from "../components/statscard";
17+
import HistoryTable from "../components/table/table";
18+
19+
import { useState } from "react";
20+
21+
export function meta() {
22+
return [
23+
{ title: "PeerPrep - Homepage" },
24+
{ name: "description", content: "Welcome to PeerPrep!" },
25+
];
26+
}
27+
28+
export default function Userpage() {
29+
const theme = useMantineTheme();
30+
31+
const [data, setData] = useState<any[]>([
32+
{
33+
question: "Two Sum",
34+
completionDate: "2024-10-01",
35+
difficulty: "Easy",
36+
topic: "Array",
37+
language: "JavaScript",
38+
},
39+
]);
40+
41+
return (
42+
<Grid>
43+
<Grid.Col span={12}>
44+
<Grid gutter="md" align="center">
45+
<Grid.Col span={{ base: 6, md: 2 }}>
46+
<StatsCard
47+
title="Interviews"
48+
stat="1,234"
49+
color={theme.colors.gray[0]}
50+
/>
51+
</Grid.Col>
52+
<Grid.Col span={{ base: 6, md: 2 }}>
53+
<StatsCard
54+
title="Easy"
55+
stat="1,234"
56+
color={theme.colors.green[5]}
57+
/>
58+
</Grid.Col>
59+
<Grid.Col span={{ base: 6, md: 2 }}>
60+
<StatsCard
61+
title="Medium"
62+
stat="1,234"
63+
color={theme.colors.yellow[5]}
64+
/>
65+
</Grid.Col>
66+
<Grid.Col span={{ base: 6, md: 2 }}>
67+
<StatsCard title="Hard" stat="1,234" color={theme.colors.red[5]} />
68+
</Grid.Col>
69+
<Grid.Col span={{ base: 12, md: 1 }} offset={{ md: 3 }}>
70+
<Button fullWidth>Queue Up</Button>
71+
</Grid.Col>
72+
</Grid>
73+
</Grid.Col>
74+
<Grid.Col span={12}>
75+
<HistoryTable
76+
data={data}
77+
/>
78+
</Grid.Col>
79+
</Grid>
80+
);
81+
}

frontend/peerprep/app/root.tsx

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
import {
2+
isRouteErrorResponse,
3+
Links,
4+
Meta,
5+
Outlet,
6+
Scripts,
7+
ScrollRestoration,
8+
useLocation,
9+
} from "react-router";
10+
11+
import "@mantine/core/styles.css";
12+
import {
13+
createTheme,
14+
MantineProvider,
15+
Container,
16+
Button,
17+
Input,
18+
Card,
19+
} from "@mantine/core";
20+
21+
import type { Route } from "./+types/root";
22+
import "./app.css";
23+
import Header from "./components/header/header";
24+
25+
export const links: Route.LinksFunction = () => [
26+
{ rel: "preconnect", href: "https://fonts.googleapis.com" },
27+
{
28+
rel: "preconnect",
29+
href: "https://fonts.gstatic.com",
30+
crossOrigin: "anonymous",
31+
},
32+
{
33+
rel: "stylesheet",
34+
href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap",
35+
},
36+
];
37+
38+
const theme = createTheme({
39+
/** mantine theme overrides */
40+
colors: {
41+
"brand-yellow": [
42+
"#fff9df",
43+
"#fff2ca",
44+
"#ffe399",
45+
"#ffd463",
46+
"#ffc736",
47+
"#ffc01e",
48+
"#ffba02",
49+
"#e4a300",
50+
"#cb9100",
51+
"#af7c00",
52+
],
53+
"custom-gray": [
54+
"#f5f5f4",
55+
"#e7e7e7",
56+
"#cdcdcd",
57+
"#b2b2b2",
58+
"#9a9a9a",
59+
"#8b8b8b",
60+
"#848484",
61+
"#717171",
62+
"#646464",
63+
"#343231",
64+
],
65+
green: [
66+
"#e5ffe5",
67+
"#cefecf",
68+
"#9ffa9f",
69+
"#6bf76b",
70+
"#48f548",
71+
"#24f324",
72+
"#0df212",
73+
"#00d701",
74+
"#00c000",
75+
"#00a600",
76+
],
77+
78+
yellow: [
79+
"#fff9df",
80+
"#fff2ca",
81+
"#ffe399",
82+
"#ffd463",
83+
"#ffc736",
84+
"#ffc01e",
85+
"#ffba02",
86+
"#e4a300",
87+
"#cb9100",
88+
"#af7c00",
89+
],
90+
91+
red: [
92+
"#ffe7e8",
93+
"#ffcece",
94+
"#ff9b9b",
95+
"#ff6464",
96+
"#fe3736",
97+
"#fe1b19",
98+
"#ff0000",
99+
"#e40000",
100+
"#cb0000",
101+
"#b20000",
102+
],
103+
},
104+
105+
components: {
106+
Button: Button.extend({
107+
defaultProps: {
108+
variant: "filled",
109+
color: "brand-yellow",
110+
c: "custom-gray.9",
111+
},
112+
}),
113+
114+
Input: Input.extend({}),
115+
116+
InputWrapper: Input.Wrapper.extend({
117+
classNames: {
118+
label: "text-white",
119+
error: "text-red-500",
120+
},
121+
}),
122+
},
123+
124+
primaryColor: "brand-yellow",
125+
primaryShade: { light: 6, dark: 6 },
126+
});
127+
128+
export function Layout({ children }: { children: React.ReactNode }) {
129+
return (
130+
<html lang="en">
131+
<head>
132+
<meta charSet="utf-8" />
133+
<meta name="viewport" content="width=device-width, initial-scale=1" />
134+
<Meta />
135+
<Links />
136+
</head>
137+
<body>
138+
{children}
139+
<ScrollRestoration />
140+
<Scripts />
141+
</body>
142+
</html>
143+
);
144+
}
145+
146+
export default function App() {
147+
const location = useLocation();
148+
const linksWithHeader = ["/user"];
149+
150+
const isHeader = () => {
151+
return linksWithHeader.includes(location.pathname);
152+
};
153+
154+
return (
155+
<MantineProvider theme={theme} defaultColorScheme="dark">
156+
{isHeader() && <Header />}
157+
<Container fluid>{<Outlet />}</Container>
158+
</MantineProvider>
159+
);
160+
}
161+
162+
export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
163+
let message = "Oops!";
164+
let details = "An unexpected error occurred.";
165+
let stack: string | undefined;
166+
167+
if (isRouteErrorResponse(error)) {
168+
message = error.status === 404 ? "404" : "Error";
169+
details =
170+
error.status === 404
171+
? "The requested page could not be found."
172+
: error.statusText || details;
173+
} else if (import.meta.env.DEV && error && error instanceof Error) {
174+
details = error.message;
175+
stack = error.stack;
176+
}
177+
178+
return (
179+
<main className="pt-16 p-4 container mx-auto">
180+
<h1>{message}</h1>
181+
<p>{details}</p>
182+
{stack && (
183+
<pre className="w-full p-4 overflow-x-auto">
184+
<code>{stack}</code>
185+
</pre>
186+
)}
187+
</main>
188+
);
189+
}

frontend/peerprep/app/routes.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { type RouteConfig, index, route } from "@react-router/dev/routes";
2+
3+
export default [
4+
index("routes/home.tsx"),
5+
route("login", "pages/login.tsx"),
6+
route("signup", "pages/signup.tsx"),
7+
route("user", "pages/userpage.tsx"),
8+
] satisfies RouteConfig;

0 commit comments

Comments
 (0)