From 00c68538fc3bcf9edd8da425d3c6085aaa594343 Mon Sep 17 00:00:00 2001 From: Pattadon Date: Mon, 27 Nov 2023 14:24:59 +0700 Subject: [PATCH 1/2] Add react-ios-time-picker package and fix merge conflict in PieChart component --- frontend/package.json | 1 + frontend/pnpm-lock.yaml | 33 ++++++- .../src/components/dashboard/PieChart.jsx | 4 - .../src/components/kanbanBoard/taskCard.jsx | 20 +---- .../kanbanBoard/taskDetailModal.jsx | 87 +++++++++++++++---- 5 files changed, 102 insertions(+), 43 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 44e4b66..b06025e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -46,6 +46,7 @@ "react-datetime-picker": "^5.5.3", "react-dom": "^18.2.0", "react-icons": "^4.11.0", + "react-ios-time-picker": "^0.2.2", "react-router-dom": "^6.18.0", "react-tsparticles": "^2.12.2", "tsparticles": "^2.12.0" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 2bb6ef0..aca0306 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -1,9 +1,5 @@ lockfileVersion: '6.0' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - dependencies: '@dnd-kit/core': specifier: ^6.1.0 @@ -113,6 +109,9 @@ dependencies: react-icons: specifier: ^4.11.0 version: 4.12.0(react@18.2.0) + react-ios-time-picker: + specifier: ^0.2.2 + version: 0.2.2(react-dom@18.2.0)(react@18.2.0) react-router-dom: specifier: ^6.18.0 version: 6.19.0(react-dom@18.2.0)(react@18.2.0) @@ -3573,6 +3572,17 @@ packages: react: 18.2.0 dev: false + /react-ios-time-picker@0.2.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-bi+K23lK6Pf2xDXmhAlz+RJuy9/onWYi7Ye+ODVhIkis9AVFECOza2ckkZl/4vUypj2+TdTsHn+VZrTNdGIwDQ==} + peerDependencies: + react: ^18.2.0 + react-dom: ^18.2.0 + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-portal: 4.2.2(react-dom@18.2.0)(react@18.2.0) + dev: false + /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -3612,6 +3622,17 @@ packages: warning: 4.0.3 dev: false + /react-portal@4.2.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-vS18idTmevQxyQpnde0Td6ZcUlv+pD8GTyR42n3CHUQq9OHi1C4jDE4ZWEbEsrbrLRhSECYiao58cvocwMtP7Q==} + peerDependencies: + react: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 + react-dom: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 + dependencies: + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /react-redux@7.2.9(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==} peerDependencies: @@ -4663,3 +4684,7 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false diff --git a/frontend/src/components/dashboard/PieChart.jsx b/frontend/src/components/dashboard/PieChart.jsx index 754ac64..c2b94c4 100644 --- a/frontend/src/components/dashboard/PieChart.jsx +++ b/frontend/src/components/dashboard/PieChart.jsx @@ -13,11 +13,7 @@ export function DonutChartGraph() { const completedTask = response.data.total_completed_tasks || 0; const donutData = [ -<<<<<<< HEAD - { name: "Completed task", count: completedTask }, -======= { name: "Completed task", count: completedTask}, ->>>>>>> 4a3f253e3049f97ef4479dd423642897a56e13fc { name: "Total task", count: totalTask }, ]; diff --git a/frontend/src/components/kanbanBoard/taskCard.jsx b/frontend/src/components/kanbanBoard/taskCard.jsx index 13817a8..179ea49 100644 --- a/frontend/src/components/kanbanBoard/taskCard.jsx +++ b/frontend/src/components/kanbanBoard/taskCard.jsx @@ -60,7 +60,7 @@ export function TaskCard({ task, deleteTask, updateTask }) { // Due Date const dueDateTag = task.end_event && new Date(task.end_event) > new Date() - ? (() => { + ? (() => { const daysUntilDue = Math.ceil((new Date(task.end_event) - new Date()) / (1000 * 60 * 60 * 24)); let colorClass = @@ -139,23 +139,6 @@ export function TaskCard({ task, deleteTask, updateTask }) { onMouseLeave={() => { setMouseIsOver(false); }}> -<<<<<<< HEAD -

document.getElementById(`task_detail_modal_${task.id}`).showModal()}> - {task.content} -

- - {mouseIsOver && ( - - )} -======= {/* -------- Task Content -------- */} {/* Tags */} {tags} @@ -183,7 +166,6 @@ export function TaskCard({ task, deleteTask, updateTask }) { {dueDateTag} {subtaskCountTag} ->>>>>>> 4a3f253e3049f97ef4479dd423642897a56e13fc ); diff --git a/frontend/src/components/kanbanBoard/taskDetailModal.jsx b/frontend/src/components/kanbanBoard/taskDetailModal.jsx index e4317e5..707572d 100644 --- a/frontend/src/components/kanbanBoard/taskDetailModal.jsx +++ b/frontend/src/components/kanbanBoard/taskDetailModal.jsx @@ -3,9 +3,21 @@ import { FaTasks, FaRegListAlt } from "react-icons/fa"; import { FaPlus } from "react-icons/fa6"; import { TbChecklist } from "react-icons/tb"; import DatePicker from "react-datepicker"; +import { TimePicker } from "react-ios-time-picker"; import "react-datepicker/dist/react-datepicker.css"; +import { borderColor } from "@mui/system"; -export function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId, updateTask }) { +export function TaskDetailModal({ + title, + description, + tags, + difficulty, + challenge, + importance, + taskId, + updateTask, +}) { + let date = new Date(); const [isChallengeChecked, setChallengeChecked] = useState(challenge); const [isImportantChecked, setImportantChecked] = useState(importance); const [currentDifficulty, setCurrentDifficulty] = useState(difficulty); @@ -15,7 +27,11 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng const [startDateEnabled, setStartDateEnabled] = useState(false); const [endDateEnabled, setEndDateEnabled] = useState(false); const [isTaskComplete, setTaskComplete] = useState(false); + const [value, setValue] = useState('10:00'); + const onChange = (timeValue) => { + setValue(timeValue); + }; const handleChallengeChange = () => { setChallengeChecked(!isChallengeChecked); }; @@ -30,7 +46,11 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng const handleTagChange = (tag) => { const isSelected = selectedTags.includes(tag); - setSelectedTags(isSelected ? selectedTags.filter((selectedTag) => selectedTag !== tag) : [...selectedTags, tag]); + setSelectedTags( + isSelected + ? selectedTags.filter((selectedTag) => selectedTag !== tag) + : [...selectedTags, tag] + ); }; const handleStartDateChange = () => { @@ -59,7 +79,8 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng const existingTags = tags.map((tag, index) => (
+ className={`text-xs inline-flex items-center font-bold leading-sm uppercase px-2 py-1 bg-${tag.color}-200 text-${tag.color}-700 rounded-full`} + > {tag.label}
)); @@ -68,7 +89,8 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng const selectedTagElements = selectedTags.map((tag, index) => (
+ className={`text-xs inline-flex items-center font-bold leading-sm uppercase px-2 py-1 bg-${tag.color}-200 text-${tag.color}-700 rounded-full`} + > {tag.label}
)); @@ -92,10 +114,16 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
-
+ +
+ +
{/* Complete? */}
@@ -147,7 +188,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
@@ -161,11 +202,19 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng -
- setDateEnd(date)} disabled={!endDateEnabled} /> +
+ setDateEnd(date)} + disabled={!endDateEnabled} + />
@@ -211,7 +260,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng @@ -226,7 +275,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng @@ -242,7 +291,11 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
- +
- +
From 0c60f48d1845dad342d9717f87543dccdf00ca27 Mon Sep 17 00:00:00 2001 From: Pattadon Date: Mon, 27 Nov 2023 15:37:39 +0700 Subject: [PATCH 2/2] Refactor navigation links and update profile component --- .../src/components/navigations/Navbar.jsx | 4 +- .../profile/ProfileUpdateComponent.jsx | 50 +++++++--- .../src/components/profile/profilePage.jsx | 92 ++++++++++++++----- 3 files changed, 108 insertions(+), 38 deletions(-) diff --git a/frontend/src/components/navigations/Navbar.jsx b/frontend/src/components/navigations/Navbar.jsx index 22120b3..a31def6 100644 --- a/frontend/src/components/navigations/Navbar.jsx +++ b/frontend/src/components/navigations/Navbar.jsx @@ -39,12 +39,12 @@ export function NavBar() { tabIndex={0} className="mt-3 z-[10] p-2 shadow menu menu-sm dropdown-content bg-base-100 rounded-box w-52">
  • - + Navigate(settings.Profile)} className="justify-between"> Profile
  • - Settings + Navigate(settings.Account)}>Settings
  • Logout diff --git a/frontend/src/components/profile/ProfileUpdateComponent.jsx b/frontend/src/components/profile/ProfileUpdateComponent.jsx index 12f5e98..a38558c 100644 --- a/frontend/src/components/profile/ProfileUpdateComponent.jsx +++ b/frontend/src/components/profile/ProfileUpdateComponent.jsx @@ -1,13 +1,30 @@ import { useState, useRef } from "react"; import { ApiUpdateUserProfile } from "src/api/UserProfileApi"; +import { axiosInstance } from "src/api/AxiosConfig"; +import { useEffect } from "react"; export function ProfileUpdateComponent() { const [file, setFile] = useState(null); - const [username, setUsername] = useState(""); - const [fullName, setFullName] = useState(""); - const [about, setAbout] = useState(""); - const defaultImage = "https://i1.sndcdn.com/artworks-cTz48e4f1lxn5Ozp-L3hopw-t500x500.jpg"; + const [firstName, setFirstName] = useState(""); + const [about, setAbout] = useState(); const fileInputRef = useRef(null); + const [profile_pic, setProfilePic] = useState(undefined); + useEffect(() => { + const fetchUser = async () => { + try { + const response = await axiosInstance.get("/user/data/"); + const fetchedProfilePic = response.data.profile_pic; + const fetchedName = response.data.first_name; + const fetchedAbout = response.data.about; + setProfilePic(fetchedProfilePic); + setAbout(fetchedAbout); + setFirstName(fetchedName); + } catch (error) { + console.error("Error fetching user:", error); + } + }; + fetchUser(); + }, []); const handleImageUpload = () => { if (fileInputRef.current) { @@ -25,7 +42,7 @@ export function ProfileUpdateComponent() { const handleSave = () => { const formData = new FormData(); formData.append("profile_pic", file); - formData.append("first_name", username); + formData.append("first_name", firstName); formData.append("about", about); ApiUpdateUserProfile(formData); @@ -45,12 +62,19 @@ export function ProfileUpdateComponent() { ref={fileInputRef} /> -
    +
    {file ? ( - Profile + Profile ) : ( <> - Default + Default @@ -58,7 +82,7 @@ export function ProfileUpdateComponent() {
    - {/* Username Field */} + {/* Username Field
    setUsername(e.target.value)} /> -
    + */} {/* Full Name Field */}
    - + setFullName(e.target.value)} />
    diff --git a/frontend/src/components/profile/profilePage.jsx b/frontend/src/components/profile/profilePage.jsx index d61368a..31284e3 100644 --- a/frontend/src/components/profile/profilePage.jsx +++ b/frontend/src/components/profile/profilePage.jsx @@ -1,36 +1,63 @@ import { ProfileUpdateComponent } from "./ProfileUpdateComponent"; +import { axiosInstance } from "src/api/AxiosConfig"; +import { useEffect, useState } from "react"; export function ProfileUpdatePage() { + const [profile_pic, setProfilePic] = useState(undefined); + const [about, setAbout] = useState(); + useEffect(() => { + const fetchUser = async () => { + try { + const response = await axiosInstance.get("/user/data/"); + const fetchedProfilePic = response.data.profile_pic; + const fetchedAbout = response.data.about; + setProfilePic(fetchedProfilePic); + setAbout(fetchedAbout); + } catch (error) { + console.error("Error fetching user:", error); + } + }; + fetchUser(); + }, []); return (
    -
    Username
    +
    Firstname
    Sirin
    -
    User ID
    + {/*
    User ID
    */}
    - + Profile Picture
    -
    + {/*
    Health
    234/3213
    - +
    32% Remain
    - -
    - + +
    */} +{/*
    Level
    @@ -40,13 +67,18 @@ export function ProfileUpdatePage() { xmlns="http://www.w3.org/2000/svg" fill="#3abff8" viewBox="0 0 24 24" - className="inline-block w-8 h-8"> + className="inline-block w-8 h-8" + >
    3213/321312321 points
    - +
    @@ -58,34 +90,43 @@ export function ProfileUpdatePage() { xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - className="inline-block w-8 h-8 stroke-current"> + className="inline-block w-8 h-8 stroke-current" + > + d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" + >
    Top 12% of Global Ranking
    - - + + */}

    About me

    - +
    -
    + {/*
    @@ -110,18 +151,21 @@ export function ProfileUpdatePage() {
    -
    +
    */}