From 2d5bb36d892d561ef4014fb282610de38cf36ed3 Mon Sep 17 00:00:00 2001 From: mar-crespo Date: Thu, 5 Feb 2026 14:46:27 -0500 Subject: [PATCH 1/4] Implementing QuestionPanel --- .../QuestionPanel/QuestionPanel.module.css | 72 +++++++++++++++++ .../QuestionPanel/QuestionPanel.tsx | 78 +++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 frontend/components/QuestionPanel/QuestionPanel.module.css create mode 100644 frontend/components/QuestionPanel/QuestionPanel.tsx diff --git a/frontend/components/QuestionPanel/QuestionPanel.module.css b/frontend/components/QuestionPanel/QuestionPanel.module.css new file mode 100644 index 0000000..89e5512 --- /dev/null +++ b/frontend/components/QuestionPanel/QuestionPanel.module.css @@ -0,0 +1,72 @@ +@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap'); + +.container { + display: flex; + flex-direction: column; + justify-self: center; + justify-content: left; + width: 70rem; +} + +.content { + font-family: 'Roboto', sans-serif; +} + +.header { + display: flex; + justify-content: left; + align-items: center; + gap: 5.5rem; + margin-bottom: 1.5rem; + height: 3.75rem; +} + +.title { + width: 55rem; + word-wrap: break-word; + + font-size: 2rem; + font-weight: 700; + color: #1e2b49; +} + +.metadata { + font-size: 0.8rem; + font-weight: 300; + color: #858ba4; + margin-bottom: 1.8rem; +} + +.details { + width: 57rem; + word-wrap: break-word; + + font-size: 1rem; + font-weight: 500; + color: #000; + margin-bottom: 1.25rem; +} + +.backButton { + display: flex; + width: 6rem; + height: 2rem; + justify-content: center; + align-items: center; + background-color: #ff5757; + color: #fff; + border: none; + border-radius: 0.375rem; + font-family: 'Roboto', sans-serif; + font-size: 0.75rem; + font-weight: 400; + cursor: pointer; + transition: + background-color 0.2s ease, + transform 0.2s ease; +} + +.backButton:hover { + background-color: #ff3131; + transform: scale(1.05); +} diff --git a/frontend/components/QuestionPanel/QuestionPanel.tsx b/frontend/components/QuestionPanel/QuestionPanel.tsx new file mode 100644 index 0000000..f1c3a02 --- /dev/null +++ b/frontend/components/QuestionPanel/QuestionPanel.tsx @@ -0,0 +1,78 @@ +import styles from './QuestionPanel.module.css'; + +interface QuestionPanelProps { + user: string; + title: string; + tags: string[]; + details: string; + create_time: Date; + user_is_anonymous: boolean; + onBack: () => void; +} + +function formatTimePassed(input: Date | string | number): string { + const now = Date.now(); + const past = new Date(input).getTime(); + + const diffMs = now - past; + if (diffMs < 0) return 'just now'; + + const seconds = Math.floor(diffMs / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + const weeks = Math.floor(days / 7); + const months = Math.floor(days / 30); + const years = Math.floor(days / 365); + + if (seconds < 60) return 'just now'; + if (minutes < 60) return `${minutes} min${minutes === 1 ? '' : 's'} ago`; + if (hours < 24) return `${hours} hr${hours === 1 ? '' : 's'} ago`; + if (days < 7) return `${days} day${days === 1 ? '' : 's'} ago`; + if (weeks < 4) return `${weeks} wk${weeks === 1 ? '' : 's'} ago`; + if (months < 12) return `${months} mo${months === 1 ? '' : 's'} ago`; + + return `${years} yr${years === 1 ? '' : 's'} ago`; +} + +function formatMetadata( + user: string, + tags: string[], + create_time: Date, + user_is_anonymous: boolean +): string { + const displayUser = user_is_anonymous == true ? 'Anonymous' : user; + const displayTag = tags[0]; + const displayTimePassed = formatTimePassed(create_time); + + return `${displayUser} • ${displayTag} • ${displayTimePassed}`; +} + +const QuestionPanel = ({ + user, + title, + tags, + details, + create_time, + user_is_anonymous, + onBack, +}: QuestionPanelProps) => { + const displayInformation = formatMetadata(user, tags, create_time, user_is_anonymous); + + return ( +
+
+
+

{title}

+ +
+

{displayInformation}

+

{details}

+
+
+ ); +}; + +export default QuestionPanel; From 8bee36ae288e43e3f9ea51e995444924a348dc7f Mon Sep 17 00:00:00 2001 From: mar-crespo Date: Wed, 11 Feb 2026 19:41:36 -0500 Subject: [PATCH 2/4] Fixing linting errors while implementing question panel --- frontend/components/QuestionPanel/QuestionPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/components/QuestionPanel/QuestionPanel.tsx b/frontend/components/QuestionPanel/QuestionPanel.tsx index f1c3a02..4a4d0fc 100644 --- a/frontend/components/QuestionPanel/QuestionPanel.tsx +++ b/frontend/components/QuestionPanel/QuestionPanel.tsx @@ -41,7 +41,7 @@ function formatMetadata( create_time: Date, user_is_anonymous: boolean ): string { - const displayUser = user_is_anonymous == true ? 'Anonymous' : user; + const displayUser = user_is_anonymous === true ? 'Anonymous' : user; const displayTag = tags[0]; const displayTimePassed = formatTimePassed(create_time); From 6819302c808c95d075f89e1934604d2f6544af0a Mon Sep 17 00:00:00 2001 From: mar-crespo Date: Tue, 17 Feb 2026 13:18:38 -0500 Subject: [PATCH 3/4] Switching to using Evergreen elements --- .../QuestionPanel/QuestionPanel.module.css | 96 ++++++++++--------- .../QuestionPanel/QuestionPanel.tsx | 23 ++--- 2 files changed, 65 insertions(+), 54 deletions(-) diff --git a/frontend/components/QuestionPanel/QuestionPanel.module.css b/frontend/components/QuestionPanel/QuestionPanel.module.css index 89e5512..ff280d9 100644 --- a/frontend/components/QuestionPanel/QuestionPanel.module.css +++ b/frontend/components/QuestionPanel/QuestionPanel.module.css @@ -1,72 +1,82 @@ @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap'); .container { - display: flex; - flex-direction: column; + display: flex !important; + flex-direction: column !important; justify-self: center; justify-content: left; - width: 70rem; + width: 70rem !important; } .content { - font-family: 'Roboto', sans-serif; + font-family: 'Roboto', sans-serif !important; } .header { - display: flex; - justify-content: left; - align-items: center; - gap: 5.5rem; - margin-bottom: 1.5rem; - height: 3.75rem; + display: flex !important; + justify-content: left !important; + align-items: center !important; + gap: 5.5rem !important; + margin-bottom: 1.5rem !important; + height: 3.75rem !important; } .title { - width: 55rem; - word-wrap: break-word; - - font-size: 2rem; - font-weight: 700; - color: #1e2b49; + width: 55rem !important; + word-wrap: break-word !important; + font-size: 2rem !important; + font-weight: 700 !important; + color: #1e2b49 !important; + margin: 0 !important; + padding: 0 !important; + line-height: 1.2 !important; } .metadata { - font-size: 0.8rem; - font-weight: 300; - color: #858ba4; - margin-bottom: 1.8rem; + font-size: 0.8rem !important; + font-weight: 300 !important; + color: #858ba4 !important; + margin-bottom: 1.8rem !important; + display: block !important; } .details { - width: 57rem; - word-wrap: break-word; - - font-size: 1rem; - font-weight: 500; - color: #000; - margin-bottom: 1.25rem; + width: 57rem !important; + word-wrap: break-word !important; + font-size: 1rem !important; + font-weight: 500 !important; + color: #000 !important; + margin-bottom: 1.25rem !important; + margin-top: 0 !important; } .backButton { - display: flex; - width: 6rem; - height: 2rem; - justify-content: center; - align-items: center; - background-color: #ff5757; - color: #fff; - border: none; - border-radius: 0.375rem; - font-family: 'Roboto', sans-serif; - font-size: 0.75rem; - font-weight: 400; - cursor: pointer; + display: flex !important; + width: 6rem !important; + height: 2rem !important; + min-width: 6rem !important; + min-height: 2rem !important; + max-width: 6rem !important; + max-height: 2rem !important; + justify-content: center !important; + align-items: center !important; + background-color: #ff5757 !important; + color: #fff !important; + border: none !important; + border-radius: 0.375rem !important; + font-family: 'Roboto', sans-serif !important; + font-size: 0.75rem !important; + font-weight: 400 !important; + cursor: pointer !important; + padding: 0 !important; + box-shadow: none !important; transition: background-color 0.2s ease, - transform 0.2s ease; + transform 0.2s ease !important; } .backButton:hover { - background-color: #ff3131; - transform: scale(1.05); + background-color: #ff3131 !important; + transform: scale(1.05) !important; + box-shadow: none !important; } diff --git a/frontend/components/QuestionPanel/QuestionPanel.tsx b/frontend/components/QuestionPanel/QuestionPanel.tsx index 4a4d0fc..3586e3d 100644 --- a/frontend/components/QuestionPanel/QuestionPanel.tsx +++ b/frontend/components/QuestionPanel/QuestionPanel.tsx @@ -1,3 +1,4 @@ +import { Pane, Heading, Button, Text, Paragraph } from 'evergreen-ui'; import styles from './QuestionPanel.module.css'; interface QuestionPanelProps { @@ -60,18 +61,18 @@ const QuestionPanel = ({ const displayInformation = formatMetadata(user, tags, create_time, user_is_anonymous); return ( -
-
-
-

{title}

- -
-

{displayInformation}

-

{details}

-
-
+ + + {displayInformation} + {details} + + ); }; From 2139647ec17b95a384ef0d2a1fa0fc774cf85569 Mon Sep 17 00:00:00 2001 From: mar-crespo Date: Tue, 17 Feb 2026 13:22:42 -0500 Subject: [PATCH 4/4] Fixing spacing between different import groups --- frontend/components/QuestionPanel/QuestionPanel.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/components/QuestionPanel/QuestionPanel.tsx b/frontend/components/QuestionPanel/QuestionPanel.tsx index 3586e3d..5c0e51e 100644 --- a/frontend/components/QuestionPanel/QuestionPanel.tsx +++ b/frontend/components/QuestionPanel/QuestionPanel.tsx @@ -1,4 +1,5 @@ import { Pane, Heading, Button, Text, Paragraph } from 'evergreen-ui'; + import styles from './QuestionPanel.module.css'; interface QuestionPanelProps {