From 64436af22a6e3cc7ef8a59034c86424475e7e126 Mon Sep 17 00:00:00 2001 From: cisel-zumbul Date: Thu, 23 Nov 2023 19:27:49 +0300 Subject: [PATCH 01/23] first draft for edit profile is added --- .../src/Components/Profile/EditProfile.tsx | 78 +++++++++++++++++++ app/frontend/src/Pages/Profile/Profile.tsx | 7 ++ app/frontend/src/router.tsx | 5 ++ 3 files changed, 90 insertions(+) create mode 100644 app/frontend/src/Components/Profile/EditProfile.tsx create mode 100644 app/frontend/src/Pages/Profile/Profile.tsx diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx new file mode 100644 index 00000000..dbf9be28 --- /dev/null +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -0,0 +1,78 @@ +import { EditFilled, PlusOutlined } from "@ant-design/icons"; +import { Button, Form, Input, Modal, Upload } from "antd"; +import { useState } from "react"; + +function EditProfile() { + const [open, setOpen] = useState(false); + const [confirmLoading, setConfirmLoading] = useState(false); + + const showModal = () => { + setOpen(true); + }; + + const handleOk = () => { + setConfirmLoading(true); + setTimeout(() => { + setOpen(false); + setConfirmLoading(false); + }, 2000); + }; + + const handleCancel = () => { + console.log("Clicked cancel button"); + setOpen(false); + }; + + const normFile = (e: any) => { + if (Array.isArray(e)) { + return e; + } + return e?.fileList; + }; + + return ( + <> + + +
+ + +
+ +
Upload
+
+
+
+ + + + + + + + + +
+
+ + ); +} + +export default EditProfile; diff --git a/app/frontend/src/Pages/Profile/Profile.tsx b/app/frontend/src/Pages/Profile/Profile.tsx new file mode 100644 index 00000000..64c75610 --- /dev/null +++ b/app/frontend/src/Pages/Profile/Profile.tsx @@ -0,0 +1,7 @@ +import EditProfile from "../../Components/Profile/EditProfile"; + +function Profile() { + return ; +} + +export default Profile; diff --git a/app/frontend/src/router.tsx b/app/frontend/src/router.tsx index 43774436..0f92e61b 100644 --- a/app/frontend/src/router.tsx +++ b/app/frontend/src/router.tsx @@ -20,6 +20,7 @@ import GiveAdminPermission from "./Pages/Admin/User/GiveAdminPermission/GiveAdmi import Groups from "./Pages/Groups/Groups"; import Group from "./Pages/Group/Group"; import CreateGroup from "./Pages/CreateGroup/CreateGroup"; +import Profile from "./Pages/Profile/Profile"; axios.defaults.headers.common["Content-Type"] = "application/json"; @@ -122,6 +123,10 @@ const router = createBrowserRouter([ path: "register", element: , }, + { + path: "profile", + element: , + }, ]); export { router }; From e04d0839d81c523f1522cce8360ac464b9609209 Mon Sep 17 00:00:00 2001 From: alperen-bircak Date: Sun, 26 Nov 2023 12:57:58 +0200 Subject: [PATCH 02/23] upload image component created --- .../UploadArea/UploadArea.module.scss | 17 ++++++ .../src/Components/UploadArea/UploadArea.tsx | 55 +++++++++++++++++++ .../Admin/Game/CreateGame/CreateGame.tsx | 13 +++-- app/frontend/src/Services/image.ts | 5 +- 4 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 app/frontend/src/Components/UploadArea/UploadArea.module.scss create mode 100644 app/frontend/src/Components/UploadArea/UploadArea.tsx diff --git a/app/frontend/src/Components/UploadArea/UploadArea.module.scss b/app/frontend/src/Components/UploadArea/UploadArea.module.scss new file mode 100644 index 00000000..3c62a0b8 --- /dev/null +++ b/app/frontend/src/Components/UploadArea/UploadArea.module.scss @@ -0,0 +1,17 @@ +.uploadContainer { + border: 2px dashed #d9d9d9; + border-radius: 4px; + padding: 16px; + text-align: center; + + &:hover { + border-color: #40a9ff; + } +} + +.dragger { + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} diff --git a/app/frontend/src/Components/UploadArea/UploadArea.tsx b/app/frontend/src/Components/UploadArea/UploadArea.tsx new file mode 100644 index 00000000..3dd7945d --- /dev/null +++ b/app/frontend/src/Components/UploadArea/UploadArea.tsx @@ -0,0 +1,55 @@ +import React, { useState } from "react"; +import { Upload } from "antd"; +import { useMutation } from "react-query"; +import axios from "axios"; +import styles from "./UploadArea.module.scss"; +import { uploadImage } from "../../Services/image"; + +interface UploadAreaProps { + style?: React.CSSProperties; + onUpload?: (url: string) => void; +} + +const UploadArea: React.FC = ({ style, onUpload }) => { + const [imageUrl, setImageUrl] = useState(null); + const uploadMutation = useMutation( + ({ image }: { image: File }) => uploadImage(image, "post-imgs"), + { + onSuccess: (data) => { + setImageUrl(data); // Assuming 'data.url' is the URL of the uploaded image + onUpload?.(data); + }, + } + ); + + const handleUpload = async (file: any) => { + uploadMutation.mutate({ image: file }); + }; + + return ( +
+ {!imageUrl ? ( + handleUpload(file)} + className={styles.dragger} + showUploadList={false} + > +

+ Click or drag file to this area to upload +

+
+ ) : ( +
+ Uploaded +
+ )} +
+ ); +}; + +export default UploadArea; diff --git a/app/frontend/src/Pages/Admin/Game/CreateGame/CreateGame.tsx b/app/frontend/src/Pages/Admin/Game/CreateGame/CreateGame.tsx index 86bd6365..d4ca26cf 100644 --- a/app/frontend/src/Pages/Admin/Game/CreateGame/CreateGame.tsx +++ b/app/frontend/src/Pages/Admin/Game/CreateGame/CreateGame.tsx @@ -58,11 +58,14 @@ function CreateGame() { }, }); - const uploadImageMutation = useMutation(uploadImage, { - onError: () => { - alert("We cannot upload the image"); - }, - }); + const uploadImageMutation = useMutation( + (i: any) => uploadImage(i, "game-icons"), + { + onError: () => { + alert("We cannot upload the image"); + }, + } + ); const handleClick = async () => { const gameIcon = await uploadImageMutation.mutateAsync( fileList[0].originFileObj diff --git a/app/frontend/src/Services/image.ts b/app/frontend/src/Services/image.ts index 0b23fb60..9cbf50c1 100644 --- a/app/frontend/src/Services/image.ts +++ b/app/frontend/src/Services/image.ts @@ -1,6 +1,5 @@ import axios from "axios"; -const FOLDER = "game-icons"; -export const uploadImage = async (image: any) => { +export const uploadImage = async (image: any, folder: string) => { const formData = new FormData(); formData.append("image", image); const config = { @@ -11,7 +10,7 @@ export const uploadImage = async (image: any) => { }; const response = await axios.post( - `${import.meta.env.VITE_APP_API_URL}/image/upload?folder=${FOLDER}`, + `${import.meta.env.VITE_APP_API_URL}/image/upload?folder=${folder}`, formData, config ); From 10215d8171011bb1466cad5092ab23572b758ecc Mon Sep 17 00:00:00 2001 From: alperen-bircak Date: Sun, 26 Nov 2023 13:08:43 +0200 Subject: [PATCH 03/23] profile route added --- app/frontend/src/Pages/Profile/Profile.module.scss | 0 app/frontend/src/Pages/Profile/Profile.tsx | 7 +++++++ app/frontend/src/router.tsx | 5 +++++ 3 files changed, 12 insertions(+) create mode 100644 app/frontend/src/Pages/Profile/Profile.module.scss create mode 100644 app/frontend/src/Pages/Profile/Profile.tsx diff --git a/app/frontend/src/Pages/Profile/Profile.module.scss b/app/frontend/src/Pages/Profile/Profile.module.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/frontend/src/Pages/Profile/Profile.tsx b/app/frontend/src/Pages/Profile/Profile.tsx new file mode 100644 index 00000000..3d106265 --- /dev/null +++ b/app/frontend/src/Pages/Profile/Profile.tsx @@ -0,0 +1,7 @@ +import styles from "./Profile.module.scss"; + +function Profile() { + return
Profile
; +} + +export default Profile; diff --git a/app/frontend/src/router.tsx b/app/frontend/src/router.tsx index 43774436..bfcb71e4 100644 --- a/app/frontend/src/router.tsx +++ b/app/frontend/src/router.tsx @@ -20,6 +20,7 @@ import GiveAdminPermission from "./Pages/Admin/User/GiveAdminPermission/GiveAdmi import Groups from "./Pages/Groups/Groups"; import Group from "./Pages/Group/Group"; import CreateGroup from "./Pages/CreateGroup/CreateGroup"; +import Profile from "./Pages/Profile/Profile"; axios.defaults.headers.common["Content-Type"] = "application/json"; @@ -104,6 +105,10 @@ const router = createBrowserRouter([ path: "admin-permission", element: , }, + { + path: "profile", + element: , + }, ], }, { From efd8fccee1d3f791566421559bfc109ba10f26fc Mon Sep 17 00:00:00 2001 From: alperen-bircak Date: Sun, 26 Nov 2023 13:14:50 +0200 Subject: [PATCH 04/23] profile page basic styling --- .../src/Pages/Profile/Profile.module.scss | 109 ++++++++++++++++++ app/frontend/src/Pages/Profile/Profile.tsx | 33 +++++- 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/app/frontend/src/Pages/Profile/Profile.module.scss b/app/frontend/src/Pages/Profile/Profile.module.scss index e69de29b..d4787ef1 100644 --- a/app/frontend/src/Pages/Profile/Profile.module.scss +++ b/app/frontend/src/Pages/Profile/Profile.module.scss @@ -0,0 +1,109 @@ +@import "../../colors"; + +.profilePage { + display: flex; + flex-direction: column; + align-items: stretch; + height: 100%; + width: 100%; + padding: 2em; + gap: 1em; + + .profileError { + height: 100%; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + } + + .profileCard { + display: flex; + justify-content: flex-start; + background-color: $yellow-light-30; + border-radius: 0.5em; + padding: 0.5em; + + .profilePicture { + flex: 1 1 0; + aspect-ratio: 1.8; + overflow: hidden; + border-radius: 0.5em; + + img { + object-fit: cover; + height: 100%; + width: 100%; + } + } + + .profileDetails { + flex: 2 2 0; + + .profileName { + height: 50%; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + h1 { + all: unset; + font-size: 2em; + font-weight: bold; + color: $prussian-blue-dark-20; + } + span { + color: $color-accent; + opacity: 80%; + } + } + + .ratingContainer { + display: flex; + justify-content: center; + align-items: center; + gap: 20px; + font-size: 50px; + color: $yellow; + } + } + } + + .profileMenu { + background-color: $prussian-blue-dark-40; + color: $color-text-light; + height: 3.5em; + border-radius: 0.5em; + display: flex; + justify-content: stretch; + align-items: stretch; + overflow: hidden; + + button { + all: unset; + flex: 1 1 0; + display: flex; + justify-content: center; + align-items: center; + transition: all 150ms ease-in-out; + text-transform: capitalize; + + &:hover, + &.active { + background-color: $blue-green; + color: $color-text; + } + &:active { + transition: all 50ms ease-in-out; + background-color: $blue-green-light-20; + } + } + } + + .profileContent { + background-color: $violet-light-80; + border-radius: 0.5em; + flex: 1 0 0px; + } +} diff --git a/app/frontend/src/Pages/Profile/Profile.tsx b/app/frontend/src/Pages/Profile/Profile.tsx index 3d106265..ce2cec8f 100644 --- a/app/frontend/src/Pages/Profile/Profile.tsx +++ b/app/frontend/src/Pages/Profile/Profile.tsx @@ -1,7 +1,38 @@ import styles from "./Profile.module.scss"; function Profile() { - return
Profile
; + const isLoading = false; + return ( +
+ {isLoading ? ( +
+ {/* Loading or error indicator goes here */} +
+ ) : ( + <> +
+
+ {/* Profile picture goes here */} +
+
+
+ {/* Profile name and additional info goes here */} +
+
+ {/* Ratings or other elements go here */} +
+
+
+
+ {/* Profile menu buttons go here */} +
+
+ {/* Profile specific content like summary, reviews, or forums goes here */} +
+ + )} +
+ ); } export default Profile; From 18c64e5d3dee83037c702a2e7c5628fe7f02c202 Mon Sep 17 00:00:00 2001 From: alperen-bircak Date: Sun, 26 Nov 2023 14:00:37 +0200 Subject: [PATCH 05/23] post image func added --- .../Forum/ForumPost/ForumPost.module.scss | 33 +++++++++++++------ .../Components/Forum/ForumPost/ForumPost.tsx | 9 +++++ .../src/Components/UploadArea/UploadArea.tsx | 3 +- app/frontend/src/Library/utils/handleError.ts | 9 +++-- .../src/Pages/ForumPost/ForumPost.module.scss | 27 +++++++++++++-- .../src/Pages/ForumPost/ForumPost.tsx | 8 +++++ .../src/Pages/ForumPostForm/ForumPostForm.tsx | 32 +++++++++++++----- app/frontend/src/Services/gamedetail.ts | 2 +- 8 files changed, 98 insertions(+), 25 deletions(-) diff --git a/app/frontend/src/Components/Forum/ForumPost/ForumPost.module.scss b/app/frontend/src/Components/Forum/ForumPost/ForumPost.module.scss index cf81e709..1214c321 100644 --- a/app/frontend/src/Components/Forum/ForumPost/ForumPost.module.scss +++ b/app/frontend/src/Components/Forum/ForumPost/ForumPost.module.scss @@ -9,17 +9,34 @@ overflow: hidden; color: $color-text; grid-template-rows: 30px 55px 35px; - grid-template-columns: 60px 1fr; + grid-template-columns: 60px min-content 1fr; grid-template-areas: - "v t" - "v c" - "v m"; + "v i t" + "v i c" + "v m m"; + + .imgConatiner { + grid-area: i; + aspect-ratio: 1; + padding: 0.5em; + img { + object-fit: contain; + height: 100%; + width: 100%; + } + } .titleContainer { display: flex; flex-direction: row; align-items: center; gap: 0.5rem; + grid-area: t; + + .title { + font-weight: bold; + font-size: 1.2em; + } } .content { @@ -51,11 +68,7 @@ } } } - .title { - font-weight: bold; - font-size: 1.2em; - grid-area: t; - } + .meta { display: flex; align-items: end; @@ -78,4 +91,4 @@ top: 0.5em; right: 0.5em; } -} \ No newline at end of file +} diff --git a/app/frontend/src/Components/Forum/ForumPost/ForumPost.tsx b/app/frontend/src/Components/Forum/ForumPost/ForumPost.tsx index ca9938dc..42c5989b 100644 --- a/app/frontend/src/Components/Forum/ForumPost/ForumPost.tsx +++ b/app/frontend/src/Components/Forum/ForumPost/ForumPost.tsx @@ -75,6 +75,15 @@ function ForumPost({ /> + {post.postImage && ( +
+ +
+ )} +
{post.title}
{isAdmin && ( diff --git a/app/frontend/src/Components/UploadArea/UploadArea.tsx b/app/frontend/src/Components/UploadArea/UploadArea.tsx index 3dd7945d..b0a1cdf7 100644 --- a/app/frontend/src/Components/UploadArea/UploadArea.tsx +++ b/app/frontend/src/Components/UploadArea/UploadArea.tsx @@ -34,6 +34,7 @@ const UploadArea: React.FC = ({ style, onUpload }) => { customRequest={({ file }) => handleUpload(file)} className={styles.dragger} showUploadList={false} + accept="image/*" >

Click or drag file to this area to upload @@ -42,7 +43,7 @@ const UploadArea: React.FC = ({ style, onUpload }) => { ) : (

Uploaded diff --git a/app/frontend/src/Library/utils/handleError.ts b/app/frontend/src/Library/utils/handleError.ts index cf15ea59..26e55298 100644 --- a/app/frontend/src/Library/utils/handleError.ts +++ b/app/frontend/src/Library/utils/handleError.ts @@ -2,8 +2,13 @@ import { message } from "antd"; export function handleError(error: any) { { - const text = - (error as Error).message ?? `Unknown Error: ${JSON.stringify(error)}`; + let text; + if (typeof error === "string") { + text == error; + } else { + text = + (error as Error).message ?? `Unknown Error: ${JSON.stringify(error)}`; + } message.error(text); console.error(error as Error); } diff --git a/app/frontend/src/Pages/ForumPost/ForumPost.module.scss b/app/frontend/src/Pages/ForumPost/ForumPost.module.scss index 8a6186be..4010c101 100644 --- a/app/frontend/src/Pages/ForumPost/ForumPost.module.scss +++ b/app/frontend/src/Pages/ForumPost/ForumPost.module.scss @@ -9,18 +9,23 @@ .postContainer { display: grid; - grid-template-rows: 80px 1fr; + grid-template-rows: 80px min-content 250px; border-radius: 0.5em; padding: 1em; background-color: $celadon; - min-height: 300px; position: relative; + gap: 0.5em; + grid-template-areas: + "t" + "i" + "b"; .edit { position: absolute; top: 0.5em; right: 0.5em; } .title { + grid-area: t; display: flex; align-items: center; gap: 0.5em; @@ -54,7 +59,25 @@ } } + .image { + grid-area: i; + min-height: 150px; + max-height: 300px; + width: 100%; + display: flex; + justify-content: center; + background-color: $vanilla-light-50; + border-radius: 0.5em; + img { + height: 100%; + width: auto; + object-fit: contain; + padding: 0.5em; + } + } + .body { + grid-area: b; padding: 0.5em; background-color: $celadon-light-30; border-radius: 0.5em; diff --git a/app/frontend/src/Pages/ForumPost/ForumPost.tsx b/app/frontend/src/Pages/ForumPost/ForumPost.tsx index abaafe17..b7cffcf1 100644 --- a/app/frontend/src/Pages/ForumPost/ForumPost.tsx +++ b/app/frontend/src/Pages/ForumPost/ForumPost.tsx @@ -94,6 +94,14 @@ function ForumPost() {

{post.title}

{" "} + {post.postImage && ( +
+ +
+ )} {post.postContent}
+
+
+ ); +} + +export default CreateAchievement; From ab674b7878a24ec11a1de143b5f2fb47b5becd61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arda=20Kabaday=C4=B1?= Date: Sun, 26 Nov 2023 16:03:18 +0300 Subject: [PATCH 08/23] add create achievement section to admin page --- app/frontend/src/Pages/Admin/Main/Main.tsx | 10 ++++++++++ app/frontend/src/router.tsx | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/app/frontend/src/Pages/Admin/Main/Main.tsx b/app/frontend/src/Pages/Admin/Main/Main.tsx index 06fa59ee..3dc356df 100644 --- a/app/frontend/src/Pages/Admin/Main/Main.tsx +++ b/app/frontend/src/Pages/Admin/Main/Main.tsx @@ -53,6 +53,16 @@ function Main() { +
+

4) Achievement

+
    +
  • + +
  • +
+
); } diff --git a/app/frontend/src/router.tsx b/app/frontend/src/router.tsx index 43774436..15030922 100644 --- a/app/frontend/src/router.tsx +++ b/app/frontend/src/router.tsx @@ -20,6 +20,7 @@ import GiveAdminPermission from "./Pages/Admin/User/GiveAdminPermission/GiveAdmi import Groups from "./Pages/Groups/Groups"; import Group from "./Pages/Group/Group"; import CreateGroup from "./Pages/CreateGroup/CreateGroup"; +import CreateAchievement from "./Pages/Admin/Achievement/CreateAchievement/CreateAchievement"; axios.defaults.headers.common["Content-Type"] = "application/json"; @@ -104,6 +105,10 @@ const router = createBrowserRouter([ path: "admin-permission", element: , }, + { + path: "create-achievement", + element: , + }, ], }, { From f9c87c7476862cea3d133a04a720c67c8a2cc218 Mon Sep 17 00:00:00 2001 From: cisel-zumbul Date: Sun, 26 Nov 2023 18:03:45 +0300 Subject: [PATCH 09/23] Adds profile editing --- .../src/Components/Profile/EditProfile.tsx | 68 +++++++++++++------ app/frontend/src/Services/profile.ts | 21 ++++++ 2 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 app/frontend/src/Services/profile.ts diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx index dbf9be28..755943aa 100644 --- a/app/frontend/src/Components/Profile/EditProfile.tsx +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -1,25 +1,24 @@ import { EditFilled, PlusOutlined } from "@ant-design/icons"; -import { Button, Form, Input, Modal, Upload } from "antd"; +import { Button, Form, Input, Modal, Radio, Upload } from "antd"; import { useState } from "react"; +import { editProfile } from "../../Services/profile"; -function EditProfile() { +function EditProfile({ editableFields }: { editableFields: any }) { const [open, setOpen] = useState(false); const [confirmLoading, setConfirmLoading] = useState(false); - const showModal = () => { setOpen(true); }; - const handleOk = () => { + const handleConfirm = async (data: any) => { setConfirmLoading(true); - setTimeout(() => { - setOpen(false); - setConfirmLoading(false); - }, 2000); + console.log(data); + await editProfile(data); + setOpen(false); + setConfirmLoading(false); }; const handleCancel = () => { - console.log("Clicked cancel button"); setOpen(false); }; @@ -30,6 +29,10 @@ function EditProfile() { return e?.fileList; }; + const onFinish = async (data: any) => { + await handleConfirm(data); + }; + return ( <> , + ]} >
@@ -60,14 +81,23 @@ function EditProfile() { - - + + + + + + private + public + + + + - - + + - - + + diff --git a/app/frontend/src/Services/profile.ts b/app/frontend/src/Services/profile.ts new file mode 100644 index 00000000..dca83d49 --- /dev/null +++ b/app/frontend/src/Services/profile.ts @@ -0,0 +1,21 @@ +import axios from "axios"; + +export async function editProfile({username, isPrivate, profilePhoto, steamProfile, epicGamesProfile, xboxProfile} : + { + username: string, + isPrivate: boolean, + profilePhoto: string, + steamProfile: string, + epicGamesProfile: string, + xboxProfile: string + }) { + await axios.post( + import.meta.env.VITE_APP_API_URL + "/profile/edit", { + username, + isPrivate, + profilePhoto, + steamProfile, + epicGamesProfile, + xboxProfile + }); +} \ No newline at end of file From 0114b1935bbe9ad43bb82867d42bfb05a2e24c9b Mon Sep 17 00:00:00 2001 From: cisel-zumbul Date: Thu, 23 Nov 2023 19:27:49 +0300 Subject: [PATCH 10/23] first draft for edit profile is added --- .../src/Components/Profile/EditProfile.tsx | 78 +++++++++++++++++++ app/frontend/src/Pages/Profile/Profile.tsx | 7 ++ app/frontend/src/router.tsx | 5 ++ 3 files changed, 90 insertions(+) create mode 100644 app/frontend/src/Components/Profile/EditProfile.tsx create mode 100644 app/frontend/src/Pages/Profile/Profile.tsx diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx new file mode 100644 index 00000000..dbf9be28 --- /dev/null +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -0,0 +1,78 @@ +import { EditFilled, PlusOutlined } from "@ant-design/icons"; +import { Button, Form, Input, Modal, Upload } from "antd"; +import { useState } from "react"; + +function EditProfile() { + const [open, setOpen] = useState(false); + const [confirmLoading, setConfirmLoading] = useState(false); + + const showModal = () => { + setOpen(true); + }; + + const handleOk = () => { + setConfirmLoading(true); + setTimeout(() => { + setOpen(false); + setConfirmLoading(false); + }, 2000); + }; + + const handleCancel = () => { + console.log("Clicked cancel button"); + setOpen(false); + }; + + const normFile = (e: any) => { + if (Array.isArray(e)) { + return e; + } + return e?.fileList; + }; + + return ( + <> + + +
+ + +
+ +
Upload
+
+
+
+ + + + + + + + + +
+
+ + ); +} + +export default EditProfile; diff --git a/app/frontend/src/Pages/Profile/Profile.tsx b/app/frontend/src/Pages/Profile/Profile.tsx new file mode 100644 index 00000000..64c75610 --- /dev/null +++ b/app/frontend/src/Pages/Profile/Profile.tsx @@ -0,0 +1,7 @@ +import EditProfile from "../../Components/Profile/EditProfile"; + +function Profile() { + return ; +} + +export default Profile; diff --git a/app/frontend/src/router.tsx b/app/frontend/src/router.tsx index 43774436..0f92e61b 100644 --- a/app/frontend/src/router.tsx +++ b/app/frontend/src/router.tsx @@ -20,6 +20,7 @@ import GiveAdminPermission from "./Pages/Admin/User/GiveAdminPermission/GiveAdmi import Groups from "./Pages/Groups/Groups"; import Group from "./Pages/Group/Group"; import CreateGroup from "./Pages/CreateGroup/CreateGroup"; +import Profile from "./Pages/Profile/Profile"; axios.defaults.headers.common["Content-Type"] = "application/json"; @@ -122,6 +123,10 @@ const router = createBrowserRouter([ path: "register", element: , }, + { + path: "profile", + element: , + }, ]); export { router }; From 6d2c0c0633694b36115ee8c0b952c2ffa8113c51 Mon Sep 17 00:00:00 2001 From: cisel-zumbul Date: Sun, 26 Nov 2023 18:03:45 +0300 Subject: [PATCH 11/23] Adds profile editing --- .../src/Components/Profile/EditProfile.tsx | 68 +++++++++++++------ app/frontend/src/Services/profile.ts | 21 ++++++ 2 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 app/frontend/src/Services/profile.ts diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx index dbf9be28..755943aa 100644 --- a/app/frontend/src/Components/Profile/EditProfile.tsx +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -1,25 +1,24 @@ import { EditFilled, PlusOutlined } from "@ant-design/icons"; -import { Button, Form, Input, Modal, Upload } from "antd"; +import { Button, Form, Input, Modal, Radio, Upload } from "antd"; import { useState } from "react"; +import { editProfile } from "../../Services/profile"; -function EditProfile() { +function EditProfile({ editableFields }: { editableFields: any }) { const [open, setOpen] = useState(false); const [confirmLoading, setConfirmLoading] = useState(false); - const showModal = () => { setOpen(true); }; - const handleOk = () => { + const handleConfirm = async (data: any) => { setConfirmLoading(true); - setTimeout(() => { - setOpen(false); - setConfirmLoading(false); - }, 2000); + console.log(data); + await editProfile(data); + setOpen(false); + setConfirmLoading(false); }; const handleCancel = () => { - console.log("Clicked cancel button"); setOpen(false); }; @@ -30,6 +29,10 @@ function EditProfile() { return e?.fileList; }; + const onFinish = async (data: any) => { + await handleConfirm(data); + }; + return ( <> , + ]} >
@@ -60,14 +81,23 @@ function EditProfile() { - - + + + + + + private + public + + + + - - + + - - + + diff --git a/app/frontend/src/Services/profile.ts b/app/frontend/src/Services/profile.ts new file mode 100644 index 00000000..dca83d49 --- /dev/null +++ b/app/frontend/src/Services/profile.ts @@ -0,0 +1,21 @@ +import axios from "axios"; + +export async function editProfile({username, isPrivate, profilePhoto, steamProfile, epicGamesProfile, xboxProfile} : + { + username: string, + isPrivate: boolean, + profilePhoto: string, + steamProfile: string, + epicGamesProfile: string, + xboxProfile: string + }) { + await axios.post( + import.meta.env.VITE_APP_API_URL + "/profile/edit", { + username, + isPrivate, + profilePhoto, + steamProfile, + epicGamesProfile, + xboxProfile + }); +} \ No newline at end of file From d91827fa011123250b54a7a060593e66f73ccb83 Mon Sep 17 00:00:00 2001 From: cisel-zumbul Date: Sun, 26 Nov 2023 18:52:29 +0300 Subject: [PATCH 12/23] Image upload is added --- .../src/Components/Profile/EditProfile.tsx | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx index 755943aa..4d100b8d 100644 --- a/app/frontend/src/Components/Profile/EditProfile.tsx +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -1,19 +1,23 @@ -import { EditFilled, PlusOutlined } from "@ant-design/icons"; -import { Button, Form, Input, Modal, Radio, Upload } from "antd"; +import { EditFilled } from "@ant-design/icons"; +import { Button, Form, Input, Modal, Radio } from "antd"; import { useState } from "react"; import { editProfile } from "../../Services/profile"; +import UploadArea from "../UploadArea/UploadArea"; function EditProfile({ editableFields }: { editableFields: any }) { const [open, setOpen] = useState(false); const [confirmLoading, setConfirmLoading] = useState(false); + const [imageUrl, setImageUrl] = useState(); + const showModal = () => { setOpen(true); }; const handleConfirm = async (data: any) => { setConfirmLoading(true); - console.log(data); - await editProfile(data); + const newdata = { ...data, ...{ profilePhoto: imageUrl } }; + console.log(newdata); + await editProfile(newdata); setOpen(false); setConfirmLoading(false); }; @@ -22,13 +26,6 @@ function EditProfile({ editableFields }: { editableFields: any }) { setOpen(false); }; - const normFile = (e: any) => { - if (Array.isArray(e)) { - return e; - } - return e?.fileList; - }; - const onFinish = async (data: any) => { await handleConfirm(data); }; @@ -68,24 +65,17 @@ function EditProfile({ editableFields }: { editableFields: any }) { layout="horizontal" id="editProfileForm" > - - -
- -
Upload
-
-
+ + - + private public From be0bf1c98db4d9a68cd98a27109401988d4a621b Mon Sep 17 00:00:00 2001 From: cisel-zumbul Date: Sun, 26 Nov 2023 19:05:11 +0300 Subject: [PATCH 13/23] Id parameter is added for edit requests --- app/frontend/src/Components/Profile/EditProfile.tsx | 9 +++------ app/frontend/src/Services/profile.ts | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx index 4d100b8d..c914229c 100644 --- a/app/frontend/src/Components/Profile/EditProfile.tsx +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -17,15 +17,13 @@ function EditProfile({ editableFields }: { editableFields: any }) { setConfirmLoading(true); const newdata = { ...data, ...{ profilePhoto: imageUrl } }; console.log(newdata); - await editProfile(newdata); + try { + await editProfile(newdata, editableFields.id); + } catch (error) {} setOpen(false); setConfirmLoading(false); }; - const handleCancel = () => { - setOpen(false); - }; - const onFinish = async (data: any) => { await handleConfirm(data); }; @@ -38,7 +36,6 @@ function EditProfile({ editableFields }: { editableFields: any }) { Date: Sun, 26 Nov 2023 19:07:33 +0300 Subject: [PATCH 14/23] Handle cancel is added back --- app/frontend/src/Components/Profile/EditProfile.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx index c914229c..83a836d0 100644 --- a/app/frontend/src/Components/Profile/EditProfile.tsx +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -4,7 +4,10 @@ import { useState } from "react"; import { editProfile } from "../../Services/profile"; import UploadArea from "../UploadArea/UploadArea"; -function EditProfile({ editableFields }: { editableFields: any }) { +function EditProfile( + { editableFields }: { editableFields: any }, + profileId: string +) { const [open, setOpen] = useState(false); const [confirmLoading, setConfirmLoading] = useState(false); const [imageUrl, setImageUrl] = useState(); @@ -18,12 +21,16 @@ function EditProfile({ editableFields }: { editableFields: any }) { const newdata = { ...data, ...{ profilePhoto: imageUrl } }; console.log(newdata); try { - await editProfile(newdata, editableFields.id); + await editProfile(newdata, profileId); } catch (error) {} setOpen(false); setConfirmLoading(false); }; + const handleCancel = () => { + setOpen(false); + }; + const onFinish = async (data: any) => { await handleConfirm(data); }; @@ -36,6 +43,7 @@ function EditProfile({ editableFields }: { editableFields: any }) { Date: Sun, 26 Nov 2023 18:49:31 +0200 Subject: [PATCH 15/23] use auth profile added --- app/frontend/src/Components/Hooks/useAuth.tsx | 19 ++++++++++++++++++- .../src/Pages/ForumPost/ForumPost.tsx | 2 +- .../src/Pages/Profile/Profile.module.scss | 4 ++-- app/frontend/src/Pages/Profile/Profile.tsx | 2 +- app/frontend/src/Services/profile.ts | 8 ++++++++ 5 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 app/frontend/src/Services/profile.ts diff --git a/app/frontend/src/Components/Hooks/useAuth.tsx b/app/frontend/src/Components/Hooks/useAuth.tsx index 2c75b5c0..f258aaec 100644 --- a/app/frontend/src/Components/Hooks/useAuth.tsx +++ b/app/frontend/src/Components/Hooks/useAuth.tsx @@ -9,6 +9,8 @@ import { useState, } from "react"; import { me } from "../../Services/me"; +import { useQuery } from "react-query"; +import { getProfile } from "../../Services/profile"; type User = any; @@ -28,6 +30,7 @@ interface UseAuthProps extends AuthContextProps { setToken: (token: string) => void; isLoggedIn: boolean; logOut: () => void; + profile: any; } // Custom hook to use auth @@ -50,7 +53,21 @@ const useAuth = (): UseAuthProps => { location.reload(); } - return { user, setUser, token, setToken, isLoggedIn: !!user, logOut }; + const { data: profile } = useQuery( + ["profile", user?.id], + () => getProfile(user?.id), + { enabled: !!user } + ); + + return { + user, + setUser, + token, + setToken, + isLoggedIn: !!user, + logOut, + profile, + }; }; // AuthProvider component diff --git a/app/frontend/src/Pages/ForumPost/ForumPost.tsx b/app/frontend/src/Pages/ForumPost/ForumPost.tsx index abaafe17..90e943ce 100644 --- a/app/frontend/src/Pages/ForumPost/ForumPost.tsx +++ b/app/frontend/src/Pages/ForumPost/ForumPost.tsx @@ -54,7 +54,7 @@ function ForumPost() {
{!isLoading && (
- {user.id === post.poster.id && ( + {user?.id === post.poster.id && (
+ ))}
+
{subPage}
)}
diff --git a/app/frontend/src/main.tsx b/app/frontend/src/main.tsx index 39fa0519..5c7ffab7 100644 --- a/app/frontend/src/main.tsx +++ b/app/frontend/src/main.tsx @@ -8,6 +8,12 @@ import { handleError } from "./Library/utils/handleError.ts"; import axios from "axios"; const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + retryDelay: 0, + }, + }, queryCache: new QueryCache({ onError(error) { handleError(error); From b8497e27da2a007af7c4e134a0178d784a2e3091 Mon Sep 17 00:00:00 2001 From: alperen-bircak Date: Sun, 26 Nov 2023 19:59:02 +0200 Subject: [PATCH 17/23] edit profile added --- .../src/Components/Profile/EditProfile.tsx | 16 +++--- .../src/Pages/Profile/Profile.module.scss | 11 +++- app/frontend/src/Pages/Profile/Profile.tsx | 54 +++++++++++++++---- app/frontend/src/Services/profile.ts | 32 +++++++++++ 4 files changed, 93 insertions(+), 20 deletions(-) diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx index 83a836d0..b1746721 100644 --- a/app/frontend/src/Components/Profile/EditProfile.tsx +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -4,10 +4,8 @@ import { useState } from "react"; import { editProfile } from "../../Services/profile"; import UploadArea from "../UploadArea/UploadArea"; -function EditProfile( - { editableFields }: { editableFields: any }, - profileId: string -) { +function EditProfile({ profile }: { profile: any }) { + const profileId = profile.id; const [open, setOpen] = useState(false); const [confirmLoading, setConfirmLoading] = useState(false); const [imageUrl, setImageUrl] = useState(); @@ -77,22 +75,22 @@ function EditProfile( /> - + - + private public - + - + - + diff --git a/app/frontend/src/Pages/Profile/Profile.module.scss b/app/frontend/src/Pages/Profile/Profile.module.scss index 6aac5fc7..01f9a456 100644 --- a/app/frontend/src/Pages/Profile/Profile.module.scss +++ b/app/frontend/src/Pages/Profile/Profile.module.scss @@ -7,6 +7,7 @@ height: 100%; width: 100%; padding: 2em; + gap: 1em; .profileError { @@ -23,6 +24,13 @@ background-color: $yellow-light-30; border-radius: 0.5em; padding: 0.5em; + position: relative; + + .edit { + position: absolute; + top: 1em; + right: 1em; + } .profilePicture { flex: 1 1 0; @@ -66,7 +74,7 @@ align-items: center; gap: 2em; - & > div { + & > a { background-color: pink; height: 3em; width: 10em; @@ -77,6 +85,7 @@ align-items: center; justify-content: space-between; padding-right: 0.5em; + text-decoration: none; img { height: 100%; diff --git a/app/frontend/src/Pages/Profile/Profile.tsx b/app/frontend/src/Pages/Profile/Profile.tsx index 61524cfd..9a02d0d8 100644 --- a/app/frontend/src/Pages/Profile/Profile.tsx +++ b/app/frontend/src/Pages/Profile/Profile.tsx @@ -4,9 +4,10 @@ import styles from "./Profile.module.scss"; import { useQueryClient } from "react-query"; import { Popover } from "antd"; import { useState } from "react"; +import EditProfile from "../../Components/Profile/EditProfile"; const subPages = ["Activities", "Games", "Eklenir Daha"]; function Profile() { - const { user, isLoading } = useAuth(); + const { user, isLoading, profile } = useAuth(); const [subPage, setSubPage] = useState(subPages[0]); return (
@@ -17,6 +18,9 @@ function Profile() { ) : ( <>
+
+ +
@@ -26,19 +30,49 @@ function Profile() { {user.email}
diff --git a/app/frontend/src/Services/profile.ts b/app/frontend/src/Services/profile.ts index 8f798b57..50000b09 100644 --- a/app/frontend/src/Services/profile.ts +++ b/app/frontend/src/Services/profile.ts @@ -6,3 +6,35 @@ export async function getProfile(id: string) { ); return response.data; } + +export async function editProfile( + { + username, + isPrivate, + profilePhoto, + steamProfile, + epicGamesProfile, + xboxProfile, + }: { + username: string; + isPrivate: boolean; + profilePhoto: string; + steamProfile: string; + epicGamesProfile: string; + xboxProfile: string; + }, + profileId: string +) { + await axios.post( + import.meta.env.VITE_APP_API_URL + "/profile/edit", + { + username, + isPrivate, + profilePhoto, + steamProfile, + epicGamesProfile, + xboxProfile, + }, + { params: { id: profileId } } + ); +} From fd1615b176c5e24c7c25815090cc315036f575b5 Mon Sep 17 00:00:00 2001 From: alperen-bircak Date: Sun, 26 Nov 2023 20:19:13 +0200 Subject: [PATCH 18/23] profile page basics done --- .../src/Components/Profile/EditProfile.tsx | 23 +++- .../src/Pages/Profile/Profile.module.scss | 3 +- app/frontend/src/Pages/Profile/Profile.tsx | 103 +++++++++++------- 3 files changed, 80 insertions(+), 49 deletions(-) diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx index b1746721..c5148d32 100644 --- a/app/frontend/src/Components/Profile/EditProfile.tsx +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -1,14 +1,23 @@ import { EditFilled } from "@ant-design/icons"; import { Button, Form, Input, Modal, Radio } from "antd"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { editProfile } from "../../Services/profile"; import UploadArea from "../UploadArea/UploadArea"; +import { useForm } from "antd/es/form/Form"; function EditProfile({ profile }: { profile: any }) { const profileId = profile.id; const [open, setOpen] = useState(false); const [confirmLoading, setConfirmLoading] = useState(false); const [imageUrl, setImageUrl] = useState(); + const [form] = useForm(); + + useEffect(() => { + console.log(profile); + form.setFieldsValue(profile); + form.setFieldValue("username", profile?.user?.username); + setImageUrl(profile?.profilePhoto); + }, [profile]); const showModal = () => { setOpen(true); @@ -60,6 +69,7 @@ function EditProfile({ profile }: { profile: any }) { Confirm Changes , ]} + forceRender >
- + - + private public - + - + - +
diff --git a/app/frontend/src/Pages/Profile/Profile.module.scss b/app/frontend/src/Pages/Profile/Profile.module.scss index 01f9a456..60c8fc9c 100644 --- a/app/frontend/src/Pages/Profile/Profile.module.scss +++ b/app/frontend/src/Pages/Profile/Profile.module.scss @@ -49,7 +49,7 @@ flex: 3 3 0; .profileName { - height: 50%; + height: 60%; width: 100%; display: flex; justify-content: center; @@ -73,6 +73,7 @@ justify-content: center; align-items: center; gap: 2em; + height: auto; & > a { background-color: pink; diff --git a/app/frontend/src/Pages/Profile/Profile.tsx b/app/frontend/src/Pages/Profile/Profile.tsx index 9a02d0d8..c4711fdb 100644 --- a/app/frontend/src/Pages/Profile/Profile.tsx +++ b/app/frontend/src/Pages/Profile/Profile.tsx @@ -19,10 +19,14 @@ function Profile() { <>
- +
- +
@@ -30,55 +34,70 @@ function Profile() { {user.email}
- - {" "} - {profile.steamProfile} - } + {!( + profile.steamProfile || + profile.epicGamesProfile || + profile.xboxProfileProfile + ) && ( + Add your game accounts by editing your profile! + )} + {profile.steamProfile && ( + - Steam Account - - - - {" "} - - {profile.epicGamesProfile} - - } + {" "} + + {profile.steamProfile} + + } + > + Steam Account + + + )} + {profile.epicGamesProfile && ( + - Epic Account - - - - {" "} - - {profile.xboxProfile} - } + + + {profile.epicGamesProfile} + + } + > + Epic Account + + + )} + {profile.xboxProfile && ( + {" "} - Xbox Account - - + + {profile.xboxProfile} + } + > + {" "} + Xbox Account + + + )}
{subPages.map((item) => ( - + ))}
{subPage}
From 1d875ea9f2318bbd5374ca253139f5d326862750 Mon Sep 17 00:00:00 2001 From: alperen-bircak Date: Sun, 26 Nov 2023 20:23:21 +0200 Subject: [PATCH 19/23] edit profile use effect fix --- app/frontend/src/Components/Profile/EditProfile.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx index c5148d32..00b4e663 100644 --- a/app/frontend/src/Components/Profile/EditProfile.tsx +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -13,7 +13,6 @@ function EditProfile({ profile }: { profile: any }) { const [form] = useForm(); useEffect(() => { - console.log(profile); form.setFieldsValue(profile); form.setFieldValue("username", profile?.user?.username); setImageUrl(profile?.profilePhoto); From 70bcb53b5ea37e12361fd41f4b534dbdd43ed435 Mon Sep 17 00:00:00 2001 From: cisel-zumbul Date: Sun, 26 Nov 2023 21:28:49 +0300 Subject: [PATCH 20/23] edit is integrated with react query --- .../src/Components/Profile/EditProfile.tsx | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/app/frontend/src/Components/Profile/EditProfile.tsx b/app/frontend/src/Components/Profile/EditProfile.tsx index b1746721..8bb16b89 100644 --- a/app/frontend/src/Components/Profile/EditProfile.tsx +++ b/app/frontend/src/Components/Profile/EditProfile.tsx @@ -3,26 +3,40 @@ import { Button, Form, Input, Modal, Radio } from "antd"; import { useState } from "react"; import { editProfile } from "../../Services/profile"; import UploadArea from "../UploadArea/UploadArea"; +import { QueryClient, useMutation } from "react-query"; +import { message } from "antd"; function EditProfile({ profile }: { profile: any }) { const profileId = profile.id; const [open, setOpen] = useState(false); const [confirmLoading, setConfirmLoading] = useState(false); const [imageUrl, setImageUrl] = useState(); + const queryClient = new QueryClient(); const showModal = () => { setOpen(true); }; + const { mutate: edit } = useMutation( + (data: any) => editProfile(data, profileId), + { + onSuccess() { + queryClient.invalidateQueries(["profile", profile.user.id]); + setConfirmLoading(false); + setOpen(false); + }, + onError(error: any) { + message.error(error.message); + setConfirmLoading(false); + }, + } + ); + const handleConfirm = async (data: any) => { setConfirmLoading(true); const newdata = { ...data, ...{ profilePhoto: imageUrl } }; console.log(newdata); - try { - await editProfile(newdata, profileId); - } catch (error) {} - setOpen(false); - setConfirmLoading(false); + edit(newdata); }; const handleCancel = () => { @@ -48,6 +62,7 @@ function EditProfile({ profile }: { profile: any }) { display: "flex", flexDirection: "column", }} + forceRender={true} footer={[