Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/workflows/commit-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Commit workflow

on: [push, pull_request]

jobs:
linux-setup-and-tests:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./frontend/peerprep
strategy:
matrix:
node-version: [20.x]
steps:
- uses: actions/checkout@v3
- name: Setup and tests with Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run lint
- run: npm run build

macos-setup-and-tests:
runs-on: macos-latest
defaults:
run:
working-directory: ./frontend/peerprep
strategy:
matrix:
node-version: [20.x]
steps:
- uses: actions/checkout@v3
- name: Setup and tests with Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run lint
- run: npm run build

windows-setup-and-tests:
runs-on: windows-latest
defaults:
run:
working-directory: ./frontend/peerprep
strategy:
matrix:
node-version: [20.x]
steps:
- uses: actions/checkout@v3
- name: Setup and tests with Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run lint
- run: npm run build
7 changes: 7 additions & 0 deletions frontend/peerprep/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ Make sure to deploy the output of `npm run build`
│ └── server/ # Server-side code
```

### Lint check
To run the lint check:

```bash
npm run lint
```

## Styling

This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer.
Expand Down
1 change: 0 additions & 1 deletion frontend/peerprep/app/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

html,
body {
@apply bg-white dark:bg-gray-950;

@media (prefers-color-scheme: dark) {
color-scheme: dark;
Expand Down
9 changes: 9 additions & 0 deletions frontend/peerprep/app/assets/images/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions frontend/peerprep/app/components/header/header.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.logo {
height: 30px;
cursor: pointer;
}

.header {
height: 56px;
margin-bottom: 20px;
background-color: var(--mantine-color-body);
border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
padding: 0 16px;
}

.inner {
height: 56px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0;
}

.link {
display: block;
line-height: 1;
padding: 8px 12px;
border-radius: var(--mantine-radius-sm);
text-decoration: none;
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0));
font-size: var(--mantine-font-size-sm);
font-weight: 500;

@mixin hover {
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
}

[data-mantine-color-scheme] &[data-active] {
background-color: var(--mantine-color-blue-filled);
color: var(--mantine-color-white);
}
}
29 changes: 29 additions & 0 deletions frontend/peerprep/app/components/header/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// With reference from official Mantine documentation
// https://ui.mantine.dev/category/headers/

import { Container, Group, Text } from "@mantine/core";
import { useNavigate } from "react-router";
import classes from "./header.module.css";
import logo from "../../assets/images/logo.svg";

export default function Header() {
const navigate = useNavigate();

return (
<header className={classes.header}>
<Container size={"md"} className={classes.inner}>
<Group>
<img
src={logo}
alt="PeerPrep Logo"
className={classes.logo}
onClick={() => navigate("/")}
/>
</Group>
<Group gap={5}>
<Text>NorbertLoh</Text>
</Group>
</Container>
</header>
);
}
18 changes: 18 additions & 0 deletions frontend/peerprep/app/components/statscard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Card, Text } from "@mantine/core";

export default function StatsCard({
title,
stat,
color,
}: {
title: string;
stat: string;
color: string;
}) {
return (
<Card shadow="sm" padding="lg">
<Text fw={700} ta="center" c="white">{stat}</Text>
<Text c={color} ta="center">{title}</Text>
</Card>
);
}
4 changes: 4 additions & 0 deletions frontend/peerprep/app/components/table/table.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.cell {
width: 150px;
text-align: right;
}
52 changes: 52 additions & 0 deletions frontend/peerprep/app/components/table/table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Button, Card, Divider, Table, Text, Pagination, Group } from "@mantine/core";
import classes from "./table.module.css";

export type InterviewHistory = {
question: string;
completionDate: string;
difficulty: string;
topic: string;
language: string;
};

export default function HistoryTable({ data }: { data: InterviewHistory[] }) {
const rows = data.map((row) => (
<Table.Tr key={row.question}>
<Table.Td>{row.question}</Table.Td>
<Table.Td ta="right">{row.completionDate}</Table.Td>
<Table.Td ta="right">{row.difficulty}</Table.Td>
<Table.Td ta="right">{row.topic}</Table.Td>
<Table.Td ta="right">{row.language}</Table.Td>
<Table.Td ta="right" style={{ width: 100 }}>
<Button>View</Button>
</Table.Td>
</Table.Tr>
));
return (
<Card shadow="sm" padding="lg">
<Text fw={1000} size="xl" c="white" mb={"xs"}>
Interviews
</Text>
<Divider />
<Table.ScrollContainer minWidth={500}>
<Table c={"white"} highlightOnHover>
<Table.Thead>
<Table.Tr>
<Table.Th>Question</Table.Th>
<Table.Th className={classes.cell}>Completion Date</Table.Th>
<Table.Th className={classes.cell}>Difficulty</Table.Th>
<Table.Th className={classes.cell}>Topic</Table.Th>
<Table.Th className={classes.cell}>Language</Table.Th>
<Table.Th className={classes.cell}></Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>{rows}</Table.Tbody>
</Table>
</Table.ScrollContainer>
<Group justify="center">
<Pagination total={5} siblings={3} defaultValue={1} />

</Group>
</Card>
);
}
70 changes: 70 additions & 0 deletions frontend/peerprep/app/pages/login.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Grid, TextInput, Button, PasswordInput, Divider, Text, Image } from "@mantine/core";
import { useForm } from "@mantine/form";
import { Link } from "react-router";
import logo from "../assets/images/logo.svg";

export function meta() {
return [
{ title: "PeerPrep - Login" },
{ name: "description", content: "Welcome to PeerPrep!" },
];
}

export default function Login() {
const form = useForm({
initialValues: {
email: "",
password: "",
},

validate: {
email: (value) => (/^\S+@\S+$/.test(value) ? null : "Invalid email"),
password: (value) =>
value.length < 6 ? "Password must be at least 6 characters" : null,
},
});

return (
<Grid>
<Grid.Col span={12}>
<Grid justify="center" gutter={"xs"} mt={{ base: 20, md: 200 }}>
<Grid.Col span={{ base: 12, md: 4 }}>
<Image src={logo} alt="PeerPrep Logo" />
<form onSubmit={form.onSubmit((values) => console.log(values))}>
<Grid.Col span={12}>
<TextInput
label="Email"
placeholder="Enter your email"
type="email"
key={form.key("email")}
{...form.getInputProps('email')}
error={undefined}
/>
</Grid.Col>
<Grid.Col span={12}>
<PasswordInput
label="Password"
placeholder="Enter your password"
type="password"
key={form.key("password")}
{...form.getInputProps('password')}
/>
</Grid.Col>
<Grid.Col span={12} mt="md">
<Button type="submit" fullWidth autoContrast>
Login
</Button>
</Grid.Col>
</form>
<Grid.Col span={12} mt="md">
<Divider my="xs" />
</Grid.Col>
<Grid.Col span={12} mt="md" className="text-center">
<Text span>Don't have an account? </Text><Link to="/signup"><Text span td="underline" c="blue" className="cursor-pointer">Sign up!</Text></Link>
</Grid.Col>
</Grid.Col>
</Grid>
</Grid.Col>
</Grid>
);
}
81 changes: 81 additions & 0 deletions frontend/peerprep/app/pages/signup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Grid, TextInput, Button, PasswordInput, Divider, Text, Image } from "@mantine/core";
import { useForm } from "@mantine/form";
import { Link } from "react-router";
import logo from "../assets/images/logo.svg";

export function meta() {
return [
{ title: "PeerPrep - Signup" },
{ name: "description", content: "Welcome to PeerPrep!" },
];
}

export default function Signup() {
const form = useForm({
initialValues: {
email: "",
username: "",
password: "",
},

validate: {
email: (value) => (/^\S+@\S+$/.test(value) ? null : "Invalid email"),
password: (value) =>
value.length < 6 ? "Password must be at least 6 characters" : null,
},
});

return (
<Grid>
<Grid.Col span={12}>
<Grid justify="center" gutter={"xs"} mt={{ base: 20, md: 200 }}>
<Grid.Col span={{ base: 12, md: 4 }}>
<Image src={logo} alt="PeerPrep Logo" />
<form onSubmit={form.onSubmit((values) => console.log(values))}>
<Grid.Col span={12}>
<TextInput
label="Email"
placeholder="Enter your email"
type="email"
key={form.key("email")}
{...form.getInputProps('email')}
error={undefined}
/>
</Grid.Col>
<Grid.Col span={12}>
<TextInput
label="Username"
placeholder="Enter your Username"
type="text"
key={form.key("username")}
{...form.getInputProps('username')}
error={undefined}
/>
</Grid.Col>
<Grid.Col span={12}>
<PasswordInput
label="Password"
placeholder="Enter your password"
type="password"
key={form.key("password")}
{...form.getInputProps('password')}
/>
</Grid.Col>
<Grid.Col span={12} mt="md">
<Button type="submit" fullWidth autoContrast>
Login
</Button>
</Grid.Col>
</form>
<Grid.Col span={12} mt="md">
<Divider my="xs" />
</Grid.Col>
<Grid.Col span={12} mt="md" className="text-center">
<Text span>Already have an account? </Text><Link to="/login"><Text span td="underline" c="blue" className="cursor-pointer">Log in!</Text></Link>
</Grid.Col>
</Grid.Col>
</Grid>
</Grid.Col>
</Grid>
);
}
Loading
Loading