aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/components/Discussions.tsx
diff options
context:
space:
mode:
authorFifthWit <fifthwitbusiness@gmail.com>2025-01-30 10:38:53 -0600
committerFifthWit <fifthwitbusiness@gmail.com>2025-01-30 10:38:53 -0600
commit608a78a31b294b468dc9daa4f1d85fc52415dab5 (patch)
tree3be7daf8e9dde906f41c470f01bdd6dfa001d082 /frontend/src/components/Discussions.tsx
parentunused var (diff)
downloadlphub-608a78a31b294b468dc9daa4f1d85fc52415dab5.tar.gz
lphub-608a78a31b294b468dc9daa4f1d85fc52415dab5.tar.bz2
lphub-608a78a31b294b468dc9daa4f1d85fc52415dab5.zip
unused var
Diffstat (limited to 'frontend/src/components/Discussions.tsx')
-rw-r--r--frontend/src/components/Discussions.tsx327
1 files changed, 215 insertions, 112 deletions
diff --git a/frontend/src/components/Discussions.tsx b/frontend/src/components/Discussions.tsx
index 17ae586..62a9fc7 100644
--- a/frontend/src/components/Discussions.tsx
+++ b/frontend/src/components/Discussions.tsx
@@ -1,34 +1,48 @@
1import React from 'react'; 1import React from "react";
2 2
3import { MapDiscussion, MapDiscussions, MapDiscussionsDetail } from '@customTypes/Map'; 3import {
4import { MapDiscussionCommentContent, MapDiscussionContent } from '@customTypes/Content'; 4 MapDiscussion,
5import { time_ago } from '@utils/Time'; 5 MapDiscussions,
6import { API } from '@api/Api'; 6 MapDiscussionsDetail,
7import "@css/Maps.css" 7} from "@customTypes/Map";
8import { Link } from 'react-router-dom'; 8import { MapDiscussionContent } from "@customTypes/Content";
9import useConfirm from '@hooks/UseConfirm'; 9import { time_ago } from "@utils/Time";
10import { API } from "@api/Api";
11import "@css/Maps.css";
12import { Link } from "react-router-dom";
13import useConfirm from "@hooks/UseConfirm";
10 14
11interface DiscussionsProps { 15interface DiscussionsProps {
12 token?: string 16 token?: string;
13 data?: MapDiscussions; 17 data?: MapDiscussions;
14 isModerator: boolean; 18 isModerator: boolean;
15 mapID: string; 19 mapID: string;
16 onRefresh: () => void; 20 onRefresh: () => void;
17} 21}
18 22
19const Discussions: React.FC<DiscussionsProps> = ({ token, data, isModerator, mapID, onRefresh }) => { 23const Discussions: React.FC<DiscussionsProps> = ({
20 24 token,
25 data,
26 isModerator,
27 mapID,
28 onRefresh,
29}) => {
21 const { confirm, ConfirmDialogComponent } = useConfirm(); 30 const { confirm, ConfirmDialogComponent } = useConfirm();
22 31
23 const [discussionThread, setDiscussionThread] = React.useState<MapDiscussion | undefined>(undefined); 32 const [discussionThread, setDiscussionThread] = React.useState<
33 MapDiscussion | undefined
34 >(undefined);
24 const [discussionSearch, setDiscussionSearch] = React.useState<string>(""); 35 const [discussionSearch, setDiscussionSearch] = React.useState<string>("");
25 36
26 const [createDiscussion, setCreateDiscussion] = React.useState<boolean>(false); 37 const [createDiscussion, setCreateDiscussion] =
27 const [createDiscussionContent, setCreateDiscussionContent] = React.useState<MapDiscussionContent>({ 38 React.useState<boolean>(false);
28 title: "", 39 const [createDiscussionContent, setCreateDiscussionContent] =
29 content: "", 40 React.useState<MapDiscussionContent>({
30 }); 41 title: "",
31 const [createDiscussionCommentContent, setCreateDiscussionCommentContent] = React.useState<string>(""); 42 content: "",
43 });
44 const [createDiscussionCommentContent, setCreateDiscussionCommentContent] =
45 React.useState<string>("");
32 46
33 const _open_map_discussion = async (discussion_id: number) => { 47 const _open_map_discussion = async (discussion_id: number) => {
34 const mapDiscussion = await API.get_map_discussion(mapID, discussion_id); 48 const mapDiscussion = await API.get_map_discussion(mapID, discussion_id);
@@ -45,13 +59,23 @@ const Discussions: React.FC<DiscussionsProps> = ({ token, data, isModerator, map
45 59
46 const _create_map_discussion_comment = async (discussion_id: number) => { 60 const _create_map_discussion_comment = async (discussion_id: number) => {
47 if (token) { 61 if (token) {
48 await API.post_map_discussion_comment(token, mapID, discussion_id, createDiscussionCommentContent); 62 await API.post_map_discussion_comment(
63 token,
64 mapID,
65 discussion_id,
66 createDiscussionCommentContent
67 );
49 await _open_map_discussion(discussion_id); 68 await _open_map_discussion(discussion_id);
50 } 69 }
51 }; 70 };
52 71
53 const _delete_map_discussion = async (discussion: MapDiscussionsDetail) => { 72 const _delete_map_discussion = async (discussion: MapDiscussionsDetail) => {
54 if (await confirm("Delete Map Discussion", `Are you sure you want to remove post: ${discussion.title}?`)) { 73 if (
74 await confirm(
75 "Delete Map Discussion",
76 `Are you sure you want to remove post: ${discussion.title}?`
77 )
78 ) {
55 if (token) { 79 if (token) {
56 await API.delete_map_discussion(token, mapID, discussion.id); 80 await API.delete_map_discussion(token, mapID, discussion.id);
57 onRefresh(); 81 onRefresh();
@@ -60,107 +84,186 @@ const Discussions: React.FC<DiscussionsProps> = ({ token, data, isModerator, map
60 }; 84 };
61 85
62 return ( 86 return (
63 <section id='section7' className='summary3'> 87 <section id="section7" className="summary3">
64 {ConfirmDialogComponent} 88 {ConfirmDialogComponent}
65 <div id='discussion-search'> 89 <div id="discussion-search">
66 <input type="text" value={discussionSearch} placeholder={"Search for posts..."} onChange={(e) => setDiscussionSearch(e.target.value)} /> 90 <input
67 <div><button onClick={() => setCreateDiscussion(true)}>New Post</button></div> 91 type="text"
92 value={discussionSearch}
93 placeholder={"Search for posts..."}
94 onChange={(e) => setDiscussionSearch(e.target.value)}
95 />
96 <div>
97 <button onClick={() => setCreateDiscussion(true)}>New Post</button>
98 </div>
68 </div> 99 </div>
69 100
70 { // janky ternary operators here, could divide them to more components? 101 {
71 createDiscussion ? 102 // janky ternary operators here, could divide them to more components?
72 ( 103 createDiscussion ? (
73 <div id='discussion-create'> 104 <div id="discussion-create">
74 <span>Create Post</span> 105 <span>Create Post</span>
75 <button onClick={() => setCreateDiscussion(false)}>X</button> 106 <button onClick={() => setCreateDiscussion(false)}>X</button>
76 <div style={{ gridColumn: "1 / span 2" }}> 107 <div style={{ gridColumn: "1 / span 2" }}>
77 <input id='discussion-create-title' placeholder='Title...' onChange={(e) => setCreateDiscussionContent({ 108 <input
78 ...createDiscussionContent, 109 id="discussion-create-title"
79 title: e.target.value, 110 placeholder="Title..."
80 })} /> 111 onChange={(e) =>
81 <input id='discussion-create-content' placeholder='Enter the content...' onChange={(e) => setCreateDiscussionContent({ 112 setCreateDiscussionContent({
82 ...createDiscussionContent, 113 ...createDiscussionContent,
83 content: e.target.value, 114 title: e.target.value,
84 })} /> 115 })
85 </div> 116 }
86 <div style={{ placeItems: "end", gridColumn: "1 / span 2" }}> 117 />
87 <button id='discussion-create-button' onClick={() => _create_map_discussion()}>Post</button> 118 <input
88 </div> 119 id="discussion-create-content"
120 placeholder="Enter the content..."
121 onChange={(e) =>
122 setCreateDiscussionContent({
123 ...createDiscussionContent,
124 content: e.target.value,
125 })
126 }
127 />
128 </div>
129 <div style={{ placeItems: "end", gridColumn: "1 / span 2" }}>
130 <button
131 id="discussion-create-button"
132 onClick={() => _create_map_discussion()}
133 >
134 Post
135 </button>
136 </div>
137 </div>
138 ) : discussionThread ? (
139 <div id="discussion-thread">
140 <div>
141 <span>{discussionThread.discussion.title}</span>
142 <button onClick={() => setDiscussionThread(undefined)}>X</button>
89 </div> 143 </div>
90 )
91 :
92 discussionThread ?
93 (
94 <div id='discussion-thread'>
95 <div>
96 <span>{discussionThread.discussion.title}</span>
97 <button onClick={() => setDiscussionThread(undefined)}>X</button>
98 </div>
99 144
100 <div> 145 <div>
101 <Link to={`/users/${discussionThread.discussion.creator.steam_id}`}> 146 <Link
102 <img src={discussionThread.discussion.creator.avatar_link} alt="" /> 147 to={`/users/${discussionThread.discussion.creator.steam_id}`}
103 </Link> 148 >
104 <div> 149 <img
105 <span>{discussionThread.discussion.creator.user_name}</span> 150 src={discussionThread.discussion.creator.avatar_link}
106 <span>{time_ago(new Date(discussionThread.discussion.created_at.replace("T", " ").replace("Z", "")))}</span> 151 alt=""
107 <span>{discussionThread.discussion.content}</span> 152 />
108 </div> 153 </Link>
109 {discussionThread.discussion.comments ? 154 <div>
110 discussionThread.discussion.comments.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()) 155 <span>{discussionThread.discussion.creator.user_name}</span>
111 .map(e => ( 156 <span>
112 <> 157 {time_ago(
113 <Link to={`/users/${e.user.steam_id}`}> 158 new Date(
114 <img src={e.user.avatar_link} alt="" /> 159 discussionThread.discussion.created_at
115 </Link> 160 .replace("T", " ")
116 <div> 161 .replace("Z", "")
117 <span>{e.user.user_name}</span> 162 )
118 <span>{time_ago(new Date(e.date.replace("T", " ").replace("Z", "")))}</span> 163 )}
119 <span>{e.comment}</span> 164 </span>
120 </div> 165 <span>{discussionThread.discussion.content}</span>
121 </> 166 </div>
122 )) : "" 167 {discussionThread.discussion.comments
123 } 168 ? discussionThread.discussion.comments
124 </div> 169 .sort(
125 <div id='discussion-send'> 170 (a, b) =>
126 <input type="text" value={createDiscussionCommentContent} placeholder={"Message"} 171 new Date(a.date).getTime() - new Date(b.date).getTime()
127 onKeyDown={(e) => e.key === "Enter" && _create_map_discussion_comment(discussionThread.discussion.id)} 172 )
128 onChange={(e) => setCreateDiscussionCommentContent(e.target.value)} /> 173 .map((e) => (
129 <div><button onClick={() => { 174 <>
175 <Link to={`/users/${e.user.steam_id}`}>
176 <img src={e.user.avatar_link} alt="" />
177 </Link>
178 <div>
179 <span>{e.user.user_name}</span>
180 <span>
181 {time_ago(
182 new Date(
183 e.date.replace("T", " ").replace("Z", "")
184 )
185 )}
186 </span>
187 <span>{e.comment}</span>
188 </div>
189 </>
190 ))
191 : ""}
192 </div>
193 <div id="discussion-send">
194 <input
195 type="text"
196 value={createDiscussionCommentContent}
197 placeholder={"Message"}
198 onKeyDown={(e) =>
199 e.key === "Enter" &&
200 _create_map_discussion_comment(discussionThread.discussion.id)
201 }
202 onChange={(e) =>
203 setCreateDiscussionCommentContent(e.target.value)
204 }
205 />
206 <div>
207 <button
208 onClick={() => {
130 if (createDiscussionCommentContent !== "") { 209 if (createDiscussionCommentContent !== "") {
131 _create_map_discussion_comment(discussionThread.discussion.id); 210 _create_map_discussion_comment(
211 discussionThread.discussion.id
212 );
132 setCreateDiscussionCommentContent(""); 213 setCreateDiscussionCommentContent("");
133 } 214 }
134 }}>Send</button></div> 215 }}
135 </div> 216 >
136 217 Send
218 </button>
137 </div> 219 </div>
138 ) 220 </div>
139 : 221 </div>
140 ( 222 ) : data ? (
141 data ? 223 <>
142 (<> 224 {data.discussions
143 {data.discussions.filter(f => f.title.includes(discussionSearch)).sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime()) 225 .filter((f) => f.title.includes(discussionSearch))
144 .map((e, i) => ( 226 .sort(
145 <div id='discussion-post'> 227 (a, b) =>
146 <button key={e.id} onClick={() => _open_map_discussion(e.id)}> 228 new Date(b.updated_at).getTime() -
147 <span>{e.title}</span> 229 new Date(a.updated_at).getTime()
148 {isModerator ? 230 )
149 <button onClick={(m) => { 231 .map((e, i) => (
150 m.stopPropagation(); 232 <div id="discussion-post">
151 _delete_map_discussion(e); 233 <button key={e.id} onClick={() => _open_map_discussion(e.id)}>
152 }}>Delete Post</button> 234 <span>{e.title}</span>
153 : <span></span> 235 {isModerator ? (
154 } 236 <button
155 <span><b>{e.creator.user_name}:</b> {e.content}</span> 237 onClick={(m) => {
156 <span>Last Updated: {time_ago(new Date(e.updated_at.replace("T", " ").replace("Z", "")))}</span> 238 m.stopPropagation();
157 </button> 239 _delete_map_discussion(e);
158 </div> 240 }}
159 ))} 241 >
160 </>) 242 Delete Post
161 : 243 </button>
162 (<span style={{ textAlign: "center", display: "block" }}>No Discussions...</span>) 244 ) : (
163 ) 245 <span></span>
246 )}
247 <span>
248 <b>{e.creator.user_name}:</b> {e.content}
249 </span>
250 <span>
251 Last Updated:{" "}
252 {time_ago(
253 new Date(
254 e.updated_at.replace("T", " ").replace("Z", "")
255 )
256 )}
257 </span>
258 </button>
259 </div>
260 ))}
261 </>
262 ) : (
263 <span style={{ textAlign: "center", display: "block" }}>
264 No Discussions...
265 </span>
266 )
164 } 267 }
165 </section> 268 </section>
166 ); 269 );