- Timestamp:
- 04/30/26 12:05:34 (2 months ago)
- Branches:
- master
- Children:
- e9a0543
- Parents:
- 8449b9c
- Location:
- frontend/src
- Files:
-
- 7 added
- 2 edited
-
App.jsx (modified) (2 diffs)
-
api/dailyCompletion.js (added)
-
api/discipline.js (added)
-
pages/Dashboard/pages/Discipline/Discipline.jsx (modified) (1 diff)
-
pages/Dashboard/pages/Discipline/DisciplineTracking.jsx (added)
-
pages/Dashboard/pages/Discipline/components/.gitkeep (added)
-
pages/Dashboard/pages/Discipline/components/DisciplineCenteredCard.jsx (added)
-
pages/Dashboard/pages/Discipline/components/DisciplineStartCtaCard.jsx (added)
-
pages/Dashboard/pages/Discipline/components/TaskList.jsx (added)
Legend:
- Unmodified
- Added
- Removed
-
frontend/src/App.jsx
r8449b9c r4f85b41 19 19 import NewInvestment from "./pages/Dashboard/pages/Investing/NewInvestment.jsx"; 20 20 import Discipline from "./pages/Dashboard/pages/Discipline/Discipline.jsx"; 21 import DisciplineTracking from "./pages/Dashboard/pages/Discipline/DisciplineTracking.jsx"; 21 22 22 23 function RequireAuth({ children }) { … … 59 60 <Route path="investing/assets/new" element={<NewInvestment />} /> 60 61 <Route path="discipline" element={<Discipline />} /> 62 <Route path="discipline/tracking" element={<DisciplineTracking />} /> 61 63 </Route> 62 64 <Route path="*" element={<Navigate to="/" replace />} /> -
frontend/src/pages/Dashboard/pages/Discipline/Discipline.jsx
r8449b9c r4f85b41 1 import React from "react"; 1 import React, { useEffect, useState } from "react"; 2 import { useNavigate } from "react-router-dom"; 2 3 3 const Discipline = () => { 4 import { 5 getDisciplineStatus, 6 startDisciplineTracking, 7 } from "../../../../api/discipline"; 8 9 import DisciplineCenteredCard from "./components/DisciplineCenteredCard.jsx"; 10 import DisciplineStartCtaCard from "./components/DisciplineStartCtaCard.jsx"; 11 12 export default function Discipline() { 13 const navigate = useNavigate(); 14 15 const [isLoading, setIsLoading] = useState(true); 16 const [isTracking, setIsTracking] = useState(false); 17 const [error, setError] = useState(""); 18 const [isSubmitting, setIsSubmitting] = useState(false); 19 20 useEffect(() => { 21 let isMounted = true; 22 const run = async () => { 23 setIsLoading(true); 24 setError(""); 25 try { 26 const tracking = await getDisciplineStatus(); 27 if (!isMounted) return; 28 setIsTracking(tracking); 29 if (tracking) { 30 navigate("/dashboard/discipline/tracking", { replace: true }); 31 } 32 } catch (err) { 33 if (!isMounted) return; 34 const message = 35 err?.response?.data?.message || "Failed to load discipline status"; 36 setError(message); 37 } finally { 38 if (isMounted) setIsLoading(false); 39 } 40 }; 41 42 run(); 43 return () => { 44 isMounted = false; 45 }; 46 }, [navigate]); 47 48 const onStart = async () => { 49 setError(""); 50 setIsSubmitting(true); 51 try { 52 await startDisciplineTracking(); 53 setIsTracking(true); 54 navigate("/dashboard/discipline/tracking", { replace: true }); 55 } catch (err) { 56 const message = 57 err?.response?.data?.message || 58 Object.values(err?.response?.data?.errors ?? {})[0] || 59 "Failed to start tracking"; 60 setError(message); 61 } finally { 62 setIsSubmitting(false); 63 } 64 }; 65 66 if (isLoading) { 67 return <DisciplineCenteredCard title="Discipline" message="Loading…" />; 68 } 69 70 if (isTracking) { 71 return <DisciplineCenteredCard title="Discipline" message="Redirecting…" />; 72 } 73 4 74 return ( 5 <div className="space-y-4"> 6 <h1 className="text-2xl font-bold">Discipline</h1> 7 <div className="card bg-base-200 border border-base-300"> 8 <div className="card-body"> 9 <p className="opacity-80">Discipline dashboard content goes here.</p> 10 </div> 75 <div className="min-h-[70vh] w-full flex items-center justify-center"> 76 <div className="w-full max-w-3xl"> 77 <DisciplineStartCtaCard 78 error={error} 79 onStart={onStart} 80 isSubmitting={isSubmitting} 81 /> 11 82 </div> 12 83 </div> 13 84 ); 14 }; 15 16 export default Discipline; 85 }
Note:
See TracChangeset
for help on using the changeset viewer.
