From a818daeb387e69f17beebf15e98bb9b7de8631c6 Mon Sep 17 00:00:00 2001 From: Romulus21 Date: Sat, 24 Feb 2024 22:54:02 +0100 Subject: [PATCH] upfate timetrackers & todo --- .../Controllers/TimeTrackerController.php | 13 ++++++-- app/Http/Controllers/ToDoController.php | 9 ++---- app/Http/Requests/ToDoRequest.php | 2 +- .../TimeTrackers/TimeTrackerEdit.tsx | 30 ++++++++++++++----- .../js/components/TimeTrackers/Tracker.tsx | 24 +++++++++++---- resources/js/hooks/TraskerHook.tsx | 3 +- resources/js/pages/TimeTrackersIndex.tsx | 8 ++++- resources/js/pages/ToDos/ToDoShow.tsx | 28 ++++++++++++++--- resources/lang/en/auth.php | 1 + 9 files changed, 89 insertions(+), 29 deletions(-) diff --git a/app/Http/Controllers/TimeTrackerController.php b/app/Http/Controllers/TimeTrackerController.php index abcd250..1218999 100644 --- a/app/Http/Controllers/TimeTrackerController.php +++ b/app/Http/Controllers/TimeTrackerController.php @@ -61,7 +61,16 @@ class TimeTrackerController extends Controller */ public function update(Request $request, TimeTracker $timeTracker) { - // + abort_if($timeTracker->toDo->user_id !== $request->user()->id, 401, __('auth.unauthorized')); + + $data = $request->validate([ + 'start_at' => ['required', 'date'], + 'end_at' => ['nullable', 'date', 'after_or_equal:start_at'], + ]); + + $timeTracker->update($data); + + return response()->json(new TimeTrackerResource($timeTracker)); } /** @@ -90,7 +99,7 @@ class TimeTrackerController extends Controller public function toDoTimeTrackers(Request $request, ToDo $toDo) { - abort_if($toDo->user_id !== $request->user()->id, 401, 'unauthoriez'); + abort_if($toDo->user_id !== $request->user()->id, 401, __('auth.unauthorized')); return response()->json(TimeTrackerResource::collection($toDo->timeTrackers->sortByDesc('start_at'))); } diff --git a/app/Http/Controllers/ToDoController.php b/app/Http/Controllers/ToDoController.php index 2321c1d..9b99157 100644 --- a/app/Http/Controllers/ToDoController.php +++ b/app/Http/Controllers/ToDoController.php @@ -44,14 +44,9 @@ class ToDoController extends Controller */ public function update(ToDoRequest $request, ToDo $todo) { - abort(501, "xoxo"); - $data = $request->validated(); - $data['checked'] = $request->input('checked') ? now() : null; - $todo->update($data); + abort_if($todo->user_id !== $request->user()->id, 401, __('auth.unauthorized')); - if ($request->user()->currentTimeTracker?->to_do_id === $todo->id) { - $request->user()->stopCurrentTimeTracker(); - } + $todo->update($request->validated()); return response()->json(new ToDoResource($todo)); } diff --git a/app/Http/Requests/ToDoRequest.php b/app/Http/Requests/ToDoRequest.php index 6f81076..e2d6769 100644 --- a/app/Http/Requests/ToDoRequest.php +++ b/app/Http/Requests/ToDoRequest.php @@ -24,7 +24,7 @@ class ToDoRequest extends FormRequest return [ 'name' => ['string', 'min:3', 'max:255'], 'description' => ['string', 'max:2000'], - 'checked' => ['boolean', 'nullable'], + 'checked' => ['nullable', 'bool'], ]; } } diff --git a/resources/js/components/TimeTrackers/TimeTrackerEdit.tsx b/resources/js/components/TimeTrackers/TimeTrackerEdit.tsx index 941942c..5c8b1ba 100644 --- a/resources/js/components/TimeTrackers/TimeTrackerEdit.tsx +++ b/resources/js/components/TimeTrackers/TimeTrackerEdit.tsx @@ -1,30 +1,45 @@ import React, {FC, FormEvent, useState} from "react" import Field from "../Field" import {timeTracker} from "../../utilities/types" +import useAxiosTools from "../../hooks/AxiosTools" -const TimeTrackerEdit: FC = ({timeTracker}) => { +const TimeTrackerEdit: FC = ({timeTracker, setReload}) => { + const {errorCatch, errorLabel, axiosPut} = useAxiosTools() const [trackerForm, setTrackerForm] = useState(timeTracker) const handleChange = (event: React.ChangeEvent) => { setTrackerForm({...trackerForm, [event.target.name]: event.target.value.replace('T', ' ')}) } - const onSubmit = (event: FormEvent) => { + const onSubmit = async (event: FormEvent) => { console.log('submit', trackerForm, event) + try { + const res = await axiosPut(`/api/time-trackers/${timeTracker.id}`, trackerForm) + setReload(res.data) + } catch (error) { + errorCatch(error) + } } - return
+ return + {errorLabel()} +

Modification de l'entrée

- + Début + + {timeTracker.end_at && + onChange={handleChange}> + Fin + } - + } @@ -32,4 +47,5 @@ export default TimeTrackerEdit interface TimeTrackerEditProps { timeTracker: timeTracker, + setReload: (elem: timeTracker) => void, } diff --git a/resources/js/components/TimeTrackers/Tracker.tsx b/resources/js/components/TimeTrackers/Tracker.tsx index 2885517..c79c5cf 100644 --- a/resources/js/components/TimeTrackers/Tracker.tsx +++ b/resources/js/components/TimeTrackers/Tracker.tsx @@ -2,11 +2,16 @@ import React, {useEffect, useState} from "react" import useTracker from "../../hooks/TraskerHook" import {Link} from "react-router-dom" import {StopSVG} from "../SVG" +import TimeTrackerEdit from "./TimeTrackerEdit" +import {Modal} from "../Modals" +import {timeTracker} from "../../utilities/types" const Tracker = () => { const [timer, setTimer] = useState('') - const {currentTimeTracker, stopCurrentTimeTrack} = useTracker() + const {currentTimeTracker, setCurrentTimeTracker, stopCurrentTimeTrack} = useTracker() + const [showTrackers, setShowTrackers] = useState(null) + const [reload, setReload] = useState(null) useEffect(() => { setTimer(formatTimer(currentTimeTracker?.start_at)) @@ -16,16 +21,19 @@ const Tracker = () => { setTimeout(() => setTimer(formatTimer(currentTimeTracker?.start_at)), 1000) }, [timer]) + useEffect(() => { + if (reload) { + setCurrentTimeTracker(reload) + setShowTrackers(null) + } + }, [reload]) + const formatTimer = (startAt: string|null|undefined) => { if (!startAt) { return '--:--' } const timer = Math.floor(((new Date()).getTime() - (new Date(startAt)).getTime()) / 1000) return Number(timer).durationify() - // let hours = Math.floor(timer / 3600) - // let minutes = Math.floor((timer - hours * 3600) / 60) - // let secondes = timer - hours * 3600 - minutes * 60 - // return `${hours}:${String(minutes).padStart(2, '0')}:${String(secondes).padStart(2, '0')}` } return
@@ -34,13 +42,17 @@ const Tracker = () => { {currentTimeTracker?.to_do?.name} - {timer} +
:
--:--
} + + setShowTrackers(null)}> + {showTrackers && } + } diff --git a/resources/js/hooks/TraskerHook.tsx b/resources/js/hooks/TraskerHook.tsx index 2203409..386412d 100644 --- a/resources/js/hooks/TraskerHook.tsx +++ b/resources/js/hooks/TraskerHook.tsx @@ -7,6 +7,7 @@ const TrackerContext = createContext(undefined) interface TrackerProps { currentTimeTracker: timeTracker|null, + setCurrentTimeTracker: (timeTracker: timeTracker) => void, startTrackToDo: (toDo: toDo) => void, stopCurrentTimeTrack: () => void, } @@ -46,7 +47,7 @@ export const TrackerProvider = ({children}: PropsWithChildren) => { } } - return + return {children} } diff --git a/resources/js/pages/TimeTrackersIndex.tsx b/resources/js/pages/TimeTrackersIndex.tsx index fa8d3d8..34bbdf9 100644 --- a/resources/js/pages/TimeTrackersIndex.tsx +++ b/resources/js/pages/TimeTrackersIndex.tsx @@ -12,12 +12,18 @@ const TimeTrackersIndex = () => { const {loading, setLoading, errorCatch, errorLabel, axiosGet} = useAxiosTools(true) const [timeTrackers, setTimeTrackers] = useState([]) const [showTrackers, setShowTrackers] = useState(null) + const [reload, setReload] = useState(null) const {startTrackToDo} = useTracker() useEffect(() => { fetchTimeTrackers() }, []) + useEffect(() => { + setShowTrackers(null) + fetchTimeTrackers() + }, [reload]) + const fetchTimeTrackers = async () => { try { const res = await axiosGet('api/time-trackers') @@ -51,7 +57,7 @@ const TimeTrackersIndex = () => { setShowTrackers(null)}> - {showTrackers && } + {showTrackers && } } diff --git a/resources/js/pages/ToDos/ToDoShow.tsx b/resources/js/pages/ToDos/ToDoShow.tsx index a6be547..96b1298 100644 --- a/resources/js/pages/ToDos/ToDoShow.tsx +++ b/resources/js/pages/ToDos/ToDoShow.tsx @@ -4,6 +4,8 @@ import useAxiosTools from "../../hooks/AxiosTools" import {timeTracker, toDo} from "../../utilities/types" import {EditSVG} from "../../components/SVG" import Field, {TextArea} from "../../components/Field" +import TimeTrackerEdit from "../../components/TimeTrackers/TimeTrackerEdit" +import {Modal} from "../../components/Modals" const ToDoShow = () => { @@ -32,6 +34,8 @@ const ToDoShow = () => { const handleEditTodoMode = async () => { if (editMode && toDo) { try { + // @ts-expect-error remove checked for update item content + delete toDo['checked'] const res = await axiosPut('/api/todos/' + id, {...toDo, name, description}) setToDo(res.data) } catch (error) { @@ -53,6 +57,7 @@ const ToDoShow = () => { : <>

{toDo?.name}

+

Terminé le {toDo?.checked ? (new Date(toDo.checked)).toSmallFrDate() : ''}

{toDo?.description}

} @@ -67,11 +72,20 @@ const ToDoTimeTrackers: FC<{toDo: toDo}> = ({toDo: toDo}) => { const {setLoading, errorCatch, errorLabel, axiosGet} = useAxiosTools(true) const [timeTrackers, setTimeTrackers] = useState([]) + const [showTrackers, setShowTrackers] = useState(null) + const [reload, setReload] = useState(null) useEffect(() => { fetchTimeTrackers() }, []) + useEffect(() => { + if (reload) { + fetchTimeTrackers() + setShowTrackers(null) + } + }, [reload]) + const fetchTimeTrackers = async () => { try { const res = await axiosGet(`/api/todos/${toDo.id}/time-trackers`) @@ -96,10 +110,6 @@ const ToDoTimeTrackers: FC<{toDo: toDo}> = ({toDo: toDo}) => { timer = Math.floor(timer / 1000) return (more ? '+' : '') + timer.durationify() - // let hours = Math.floor(timer / 3600) - // let minutes = Math.floor((timer - hours * 3600) / 60) - // let secondes = timer - hours * 3600 - minutes * 60 - // return `${more ? '+' : ''} ${hours}:${String(minutes).padStart(2, '0')}:${String(secondes).padStart(2, '0')}` } return
@@ -111,6 +121,7 @@ const ToDoTimeTrackers: FC<{toDo: toDo}> = ({toDo: toDo}) => { Début Fin Différence + @@ -118,8 +129,17 @@ const ToDoTimeTrackers: FC<{toDo: toDo}> = ({toDo: toDo}) => { {timeTracker.start_at ? (new Date(timeTracker.start_at)).toSmallFrDate() : ''} {timeTracker.end_at ? (new Date(timeTracker.end_at)).toSmallFrDate() : ''} {timeTracker.start_at && timeTracker.end_at ? (new Date(timeTracker.end_at)).difference(new Date(timeTracker.start_at)) : ''} + + + )} + + setShowTrackers(null)}> + {showTrackers && } +
} diff --git a/resources/lang/en/auth.php b/resources/lang/en/auth.php index 6598e2c..42acfee 100644 --- a/resources/lang/en/auth.php +++ b/resources/lang/en/auth.php @@ -16,5 +16,6 @@ return [ 'failed' => 'These credentials do not match our records.', 'password' => 'The provided password is incorrect.', 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', + 'unauthorized' => 'Unauthorized action', ];