diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index 87f3b10..9564e24 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -51,6 +51,7 @@ async function Content({ children }: ContentProps): Promise { { title: 'About', href: '/about' }, { title: 'Study Groups', href: '/study-groups' }, { title: 'Q&A', href: '/questions' }, + { title: 'My Posts', href: '/my-posts' }, ]; return ( diff --git a/frontend/app/my-posts/page.tsx b/frontend/app/my-posts/page.tsx new file mode 100644 index 0000000..fd45188 --- /dev/null +++ b/frontend/app/my-posts/page.tsx @@ -0,0 +1,126 @@ +/** + * @overview My Posts page — displays all Q&A activity for the current user. + * + * Copyright © 2021-2025 Hoagie Club and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree or at https://github.com/hoagieclub/help/LICENSE. + * + * Permission is granted under the MIT License to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the software. This software is provided "as-is", without warranty of any kind. + */ + +'use client'; + +import { useRouter } from 'next/navigation'; + +import { + UserPostsDashboard, + type UserPostQuestion, + type UserPostAnswer, + type UserPostComment, + type UserPostsUser, +} from '@/components/UserPostsDashboard'; + +/* ------------------------------------------------------------------ */ +/* Sample data for preview */ +/* ------------------------------------------------------------------ */ + +const sampleUser: UserPostsUser = { + name: 'Alex Chen', + email: 'achen@princeton.edu', + classYear: 2026, +}; + +const sampleQuestions: UserPostQuestion[] = [ + { + id: 1, + title: 'Best strategies for COS 226 midterm prep?', + details: + 'I have my midterm coming up in two weeks and I\'m looking for effective study strategies. Has anyone found particular resources or practice problems that helped them the most?', + tags: ['exam prep', 'study tips'], + course: 'COS 226', + hearts: 12, + views: 89, + createdAt: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(), // 2h ago + }, + { + id: 2, + title: 'How to cite sources in ORF 245 final paper?', + details: + 'The professor mentioned APA format but I\'m not sure if that applies to the statistical appendix as well. Any guidance from people who took this last semester?', + tags: ['citation'], + course: 'ORF 245', + hearts: 5, + views: 34, + createdAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(), // 3d ago + }, + { + id: 3, + title: 'Should I take COS 340 or MAT 375?', + details: + 'Both cover similar topics but I\'ve heard very different things about workload and teaching style. Would love to hear from anyone who\'s taken either.', + tags: ['course selection', 'course advice'], + course: null, + hearts: 8, + views: 112, + createdAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(), // 1w ago + }, +]; + +const sampleAnswers: UserPostAnswer[] = [ + { + id: 1, + questionId: 10, + questionTitle: 'Tips for getting started with research as a sophomore?', + text: 'I started by emailing professors whose work I found interesting after reading a couple of their papers. Most are very receptive to undergrads — just be specific about why their research excites you.', + hearts: 7, + createdAt: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(), // 1d ago + }, + { + id: 2, + questionId: 15, + questionTitle: 'What\'s the best way to study for orgo?', + text: 'Practice problems are everything. I worked through every problem in the Klein textbook and that alone got me through the class. The mechanism drills on Organic Chemistry Tutor (YouTube) are also great.', + hearts: 15, + createdAt: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString(), // 5d ago + }, +]; + +const sampleComments: UserPostComment[] = [ + { + id: 1, + answerId: 20, + questionTitle: 'Is it worth doing a certificate in finance as a BSE student?', + text: 'Totally agree with this — I did the same and it opened a lot of doors for internship applications.', + hearts: 3, + createdAt: new Date(Date.now() - 4 * 60 * 60 * 1000).toISOString(), // 4h ago + }, + { + id: 2, + answerId: 25, + questionTitle: 'How to balance extracurriculars and coursework?', + text: 'The time-blocking strategy mentioned here really works. I\'d also add that saying no to things is an underrated skill.', + hearts: 6, + createdAt: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(), // 2d ago + }, +]; + +/* ------------------------------------------------------------------ */ +/* Page component */ +/* ------------------------------------------------------------------ */ + +export default function MyPostsPage() { + const router = useRouter(); + + return ( + router.push(`/questions/${id}`)} + onAnswerClick={(questionId) => router.push(`/questions/${questionId}`)} + /> + ); +} diff --git a/frontend/app/questions/ask/page.tsx b/frontend/app/questions/ask/page.tsx new file mode 100644 index 0000000..e54788d --- /dev/null +++ b/frontend/app/questions/ask/page.tsx @@ -0,0 +1,7 @@ +'use client'; + +import AskQuestion from '@/components/AskQuestion'; + +export default function AskQuestionPage() { + return ; +} diff --git a/frontend/app/questions/page.tsx b/frontend/app/questions/page.tsx index 49164e3..bf50f5a 100644 --- a/frontend/app/questions/page.tsx +++ b/frontend/app/questions/page.tsx @@ -3,8 +3,11 @@ import AccessTimeIcon from '@mui/icons-material/AccessTime'; import AddIcon from '@mui/icons-material/Add'; import { Button, Heading, Pane, Text, TrendingUpIcon, majorScale } from 'evergreen-ui'; +import { useRouter } from 'next/navigation'; export function QAPage() { + const router = useRouter(); + /** * Handles the recent button click */ @@ -23,7 +26,7 @@ export function QAPage() { * Handles the ask question button click */ const askQuestionHandler = () => { - // Placeholder for button click action + router.push('/questions/ask'); }; return ( diff --git a/frontend/app/study-groups/page.tsx b/frontend/app/study-groups/page.tsx index 07b4c14..ad8fb1c 100644 --- a/frontend/app/study-groups/page.tsx +++ b/frontend/app/study-groups/page.tsx @@ -12,69 +12,16 @@ 'use client'; -import type { ChangeEvent } from 'react'; -import { useState } from 'react'; - -import { Button, Heading, Pane, Text, TextInputField, majorScale } from 'evergreen-ui'; -import Link from 'next/link'; +import { StudyGroupsDashboard } from '@/components/StudyGroupsDashboard'; /** - * A React component that renders a form for user interaction, allowing users to input their name - * and select an option from a dropdown menu. It uses Evergreen UI components for styling and - * integrates with Auth0 for user authentication. The form submission triggers an async action that - * simulates an API call and provides feedback through toast notifications. - * - * @returns {JSX.Element} The form component with user interaction elements. + * Study Groups page: find classmates and create study groups. */ export function StudyGroups() { - /** - * Handles the input field which can perform queries - */ - const [inputValue, setInputValue] = useState(''); - const handleChange = (e: ChangeEvent) => { - setInputValue(e.target.value); - }; - - /** - * Handles the button click - */ - const handleSubmit = () => { - // Placeholder for button click action - }; - return ( - - {/* Main header */} - - Study Groups - - - {/* Subtitle */} - - Find classmates and form study groups - - - - - - - - - +
+ +
); } diff --git a/frontend/components/AskQuestion.tsx b/frontend/components/AskQuestion.tsx index 5e727e0..3bd5814 100644 --- a/frontend/components/AskQuestion.tsx +++ b/frontend/components/AskQuestion.tsx @@ -2,7 +2,8 @@ import React, { useState } from 'react'; -import { Pane, Textarea, Button, majorScale, minorScale } from 'evergreen-ui'; +import { ArrowLeftIcon, Button, Heading, Pane, Text, Textarea, majorScale } from 'evergreen-ui'; +import { useRouter } from 'next/navigation'; interface FormState { questionTitle: string; @@ -19,9 +20,9 @@ const initialFormState: FormState = { }; export default function AskQuestion(): React.ReactElement { + const router = useRouter(); const [form, setForm] = useState(initialFormState); const [submitted, setSubmitted] = useState(false); - const [canceled, setCanceled] = useState(false); const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target as HTMLInputElement; @@ -38,106 +39,159 @@ export default function AskQuestion(): React.ReactElement { const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); setSubmitted(true); - setCanceled(false); setForm(initialFormState); }; const handleCancel = () => { setForm(initialFormState); - setSubmitted(false); - setCanceled(true); + router.push('/questions'); + }; + + const handleBack = () => { + router.push('/questions'); }; return ( - -

Ask a Question

-

- Get help from the Princeton academics community -

-
-
- - -
- -
- - -
- -
- - -
- -
- -