Skip to content

Commit d59dd85

Browse files
committed
Basic addquestion page
Todo: Hook up with the form
1 parent 386d863 commit d59dd85

File tree

16 files changed

+1273
-23
lines changed

16 files changed

+1273
-23
lines changed

.lefthook.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pre-push:
1+
pre-commit:
22
parallel: true
33
commands:
44
golangci-lint:

peerprep/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pnpm dev
2323

2424
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
2525

26-
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
26+
You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
2727

2828
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and
2929
load Inter, a custom Google Font.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
export const exampleQuestion = `
2+
<!-- This is an example question, replace with your own. Remove this line! -->
3+
<p>Given an integer array nums, return all the triplets
4+
\t<code>[nums[i], nums[j], nums[k]]</code> such that
5+
\t<code>i != j</code>,
6+
\t<code>i != k</code>, and
7+
\t<code>j != k</code>, and
8+
\t<code>nums[i] + nums[j] + nums[k] == 0</code>.
9+
</p>\n\n
10+
<p>Notice that the solution set must not contain duplicate triplets.</p>\n\n
11+
<p>&nbsp;</p>\n
12+
13+
<p>
14+
\t<strong class=\\"example\\">Example 1:</strong>
15+
</p>\n\n
16+
17+
\n
18+
19+
<p>\t<strong>Input:</strong> nums = [-1,0,1,2,-1,-4]\n\n
20+
</p>
21+
<p>\t<strong>Output:</strong> [[-1,-1,2],[-1,0,1]]\n</p>
22+
<p>\t<strong>Explanation:</strong> \nnums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0.\nnums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0.\nnums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0.\nThe distinct triplets are [-1,0,1] and [-1,-1,2].\nNotice that the order of the output and the order of the triplets does not matter.\n</p>
23+
\n\n
24+
25+
26+
<p>
27+
\t<strong class=\\"example\\">Example 2:</strong>
28+
</p>\n\n
29+
30+
<pre>\n
31+
\t<strong>Input:</strong> nums = [0,1,1]\n
32+
\t<strong>Output:</strong> []\n
33+
\t<strong>Explanation:</strong> The only possible triplet does not sum up to 0.\n
34+
</pre>\n\n
35+
36+
<p>
37+
\t<strong class=\\"example\\">Example 3:</strong>
38+
</p>\n\n
39+
40+
<pre>\n
41+
\t<strong>Input:</strong> nums = [0,0,0]\n
42+
\t<strong>Output:</strong> [[0,0,0]]\n
43+
\t<strong>Explanation:</strong> The only possible triplet sums up to 0.\n
44+
</pre>\n\n
45+
46+
<p>&nbsp;</p>\n
47+
<p>
48+
\t<strong>Constraints:</strong>
49+
</p>\n\n
50+
<ul>\n\t
51+
\t<li>
52+
\t\t<code>3 &lt;= nums.length &lt;= 3000</code>
53+
\t</li>\n\t
54+
\t<li>
55+
\t\t<code>-10
56+
\t\t\t<sup>5</sup> &lt;= nums[i] &lt;= 10
57+
\t\t\t<sup>5</sup>
58+
\t\t</code>
59+
\t</li>\n
60+
</ul>\n",
61+
`;
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import styles from "@/style/addquestion.module.css";
2+
3+
import React from "react";
4+
import { Editor } from "@tiptap/core";
5+
import {
6+
Bold,
7+
Code,
8+
Italic,
9+
List,
10+
ListOrdered,
11+
Redo,
12+
RemoveFormatting,
13+
Strikethrough,
14+
Underline,
15+
Undo,
16+
} from "lucide-react";
17+
import Tooltip from "./Tooltip";
18+
19+
type Props = {
20+
editor: Editor | null;
21+
};
22+
23+
export const MenuBar = ({ editor }: Props) => {
24+
if (!editor) {
25+
return null;
26+
}
27+
28+
return (
29+
<div className={styles.buttonGroup}>
30+
<Tooltip text="Clear formatting">
31+
<button
32+
onClick={() => editor.commands.unsetAllMarks()}
33+
className={styles.button}
34+
>
35+
<RemoveFormatting className="h-5 w-5" />
36+
</button>
37+
</Tooltip>
38+
<Tooltip text="Bold">
39+
<button
40+
onClick={() => editor.chain().focus().toggleBold().run()}
41+
className={`${styles.button} ${editor.isActive("bold") ? styles.isActive : ""}`}
42+
>
43+
<Bold className="h-5 w-5" />
44+
</button>
45+
</Tooltip>
46+
47+
<Tooltip text="Italics">
48+
<button
49+
onClick={() => editor.chain().focus().toggleItalic().run()}
50+
className={`${styles.button} ${editor.isActive("italic") ? styles.isActive : ""}`}
51+
>
52+
<Italic className="h-5 w-5" />
53+
</button>
54+
</Tooltip>
55+
56+
<Tooltip text="Underline">
57+
<button
58+
onClick={() => editor.chain().focus().toggleUnderline().run()}
59+
className={`${styles.button} ${editor.isActive("underline") ? styles.isActive : ""}`}
60+
>
61+
<Underline className="h-5 w-5" />
62+
</button>
63+
</Tooltip>
64+
65+
<Tooltip text="Strikethrough">
66+
<button
67+
onClick={() => editor.chain().focus().toggleStrike().run()}
68+
className={`${styles.button} ${editor.isActive("strike") ? styles.isActive : ""}`}
69+
>
70+
<Strikethrough className="h-5 w-5" />
71+
</button>
72+
</Tooltip>
73+
74+
<Tooltip text="Code">
75+
<button
76+
onClick={() => editor.chain().focus().toggleCode().run()}
77+
className={`${styles.button} ${editor.isActive("code") ? styles.isActive : ""}`}
78+
>
79+
<Code className="h-5 w-5" />
80+
</button>
81+
</Tooltip>
82+
83+
<Tooltip text="CodeBlock">
84+
<button
85+
onClick={() => editor.chain().focus().toggleCode().run()}
86+
className={`${styles.button} ${editor.isActive("code") ? styles.isActive : ""}`}
87+
>
88+
<Code className="h-5 w-5" />
89+
</button>
90+
</Tooltip>
91+
92+
<Tooltip text="Numbered list">
93+
<button
94+
onClick={() => editor.chain().focus().toggleOrderedList().run()}
95+
className={styles.button}
96+
>
97+
<ListOrdered className="h-5 w-5" />
98+
</button>
99+
</Tooltip>
100+
101+
<Tooltip text="Bullet list">
102+
<button
103+
onClick={() => editor.chain().focus().toggleBulletList().run()}
104+
className={styles.button}
105+
>
106+
<List className="h-5 w-5" />
107+
</button>
108+
</Tooltip>
109+
110+
<Tooltip text="Undo">
111+
<button
112+
onClick={() => editor.chain().focus().undo().run()}
113+
disabled={!editor.can().undo()}
114+
className={styles.button}
115+
>
116+
<Undo className="h-5 w-5" />
117+
</button>
118+
</Tooltip>
119+
120+
<Tooltip text="Redo">
121+
<button
122+
onClick={() => editor.chain().focus().redo().run()}
123+
disabled={!editor.can().redo()}
124+
className={styles.button}
125+
>
126+
<Redo className="h-5 w-5" />
127+
</button>
128+
</Tooltip>
129+
</div>
130+
);
131+
};
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"use client";
2+
3+
import "@/style/tiptap.css";
4+
import { EditorContent, useEditor } from "@tiptap/react";
5+
import StarterKit from "@tiptap/starter-kit";
6+
import React from "react";
7+
import { exampleQuestion } from "@/app/questions/newquestion/ExampleQuestion";
8+
import { Placeholder } from "@tiptap/extension-placeholder";
9+
import { Subscript } from "@tiptap/extension-subscript";
10+
import { Superscript } from "@tiptap/extension-superscript";
11+
import { Link } from "@tiptap/extension-link";
12+
import { Underline } from "@tiptap/extension-underline";
13+
import { MenuBar } from "@/app/questions/newquestion/MenuBar";
14+
// load all languages with "all" or common languages with "common"
15+
16+
// create a lowlight instance with all languages loaded
17+
18+
const Tiptap = () => {
19+
const editor = useEditor({
20+
extensions: [
21+
StarterKit,
22+
Subscript,
23+
Superscript,
24+
Underline,
25+
26+
Link,
27+
Placeholder.configure({
28+
placeholder: "Add your question here",
29+
}),
30+
],
31+
content: exampleQuestion,
32+
immediatelyRender: false,
33+
});
34+
35+
return (
36+
<div className="h-96">
37+
<MenuBar editor={editor} />
38+
<div className="editor-content h-80 resize-y overflow-y-auto rounded-md border bg-gray-1 p-2">
39+
<EditorContent editor={editor} />
40+
</div>
41+
</div>
42+
);
43+
};
44+
45+
export default Tiptap;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from "react";
2+
import styles from "@/style/addquestion.module.css";
3+
4+
type TooltipProps = {
5+
text: string;
6+
children: React.ReactNode;
7+
};
8+
9+
const Tooltip = ({ text, children }: TooltipProps) => {
10+
return (
11+
<div className={styles.tooltipWrapper}>
12+
{children}
13+
<span className={styles.tooltip}>{text}</span>
14+
</div>
15+
);
16+
};
17+
18+
export default Tooltip;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import Tiptap from "@/app/questions/newquestion/Tiptap";
2+
3+
const NewQuestion = () => {
4+
return (
5+
<div className="flex flex-col items-center">
6+
<h1 className="mt-8 text-center text-3xl font-bold">
7+
Create a new question
8+
</h1>
9+
10+
<div className="mt-4 w-full max-w-screen-md px-4">
11+
<p className="mb-2 text-left text-lg font-medium">Title</p>
12+
<input
13+
type="text"
14+
className="cur mb-4 w-full rounded-md border p-2 text-black caret-black"
15+
placeholder="Enter question title"
16+
/>
17+
18+
<p className="mb-2 text-left text-lg font-medium">Difficulty</p>
19+
<input
20+
type="text"
21+
className="mb-4 w-full rounded-md border p-2 text-black caret-black"
22+
placeholder="Enter question difficulty"
23+
/>
24+
25+
<p className="mb-2 text-left text-lg font-medium">Question Content</p>
26+
<div>
27+
<Tiptap />
28+
</div>
29+
</div>
30+
</div>
31+
);
32+
};
33+
34+
export default NewQuestion;

peerprep/components/home/Carousel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useState, useEffect, useRef } from "react";
22
import { AnimatePresence, motion, MotionConfig } from "framer-motion";
3-
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/24/outline";
3+
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
44

55
// code adapted from https://buildui.com/courses/framer-motion-recipes/carousel-part-1
66

peerprep/components/navbar/Navbar.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
DisclosureButton,
66
DisclosurePanel,
77
} from "@headlessui/react";
8-
import { Bars3Icon, XMarkIcon } from "@heroicons/react/24/outline";
8+
import { Menu, X } from "lucide-react";
99
import Image from "next/image";
1010
import { ProfileDropdown } from "@/components/navbar/ProfileDropdown";
1111

@@ -29,11 +29,11 @@ const MobileMenu = () => {
2929
<DisclosureButton className="group relative inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white">
3030
<span className="absolute -inset-0.5" />
3131
<span className="sr-only">Open main menu</span>
32-
<Bars3Icon
32+
<Menu
3333
aria-hidden="true"
3434
className="block h-6 w-6 group-data-[open]:hidden"
3535
/>
36-
<XMarkIcon
36+
<X
3737
aria-hidden="true"
3838
className="hidden h-6 w-6 group-data-[open]:block"
3939
/>

peerprep/components/shared/PeerprepSearchBar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// PeerprepSearchBar.tsx
22
import React from "react";
33
import styles from "@/style/elements.module.css";
4-
import { MagnifyingGlassIcon } from "@heroicons/react/16/solid";
4+
import { Search } from "lucide-react";
55

66
interface PeerprepSearchBarProps {
77
value: string;
@@ -16,7 +16,7 @@ const PeerprepSearchBar: React.FC<PeerprepSearchBarProps> = ({
1616
}) => {
1717
return (
1818
<div className="relative">
19-
<MagnifyingGlassIcon className="pointer-events-none absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 transform text-gray-400" />
19+
<Search className="pointer-events-none absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 transform text-gray-400" />
2020
<input
2121
type="text"
2222
placeholder={label}

0 commit comments

Comments
 (0)