Changeset 4f85b41


Ignore:
Timestamp:
04/30/26 12:05:34 (2 months ago)
Author:
Andrej <asumanovski@…>
Branches:
master
Children:
e9a0543
Parents:
8449b9c
Message:

Daily discipline feature done

Files:
22 added
1 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • backend/src/main/java/com/trekr/backend/config/SecurityConfig.java

    r8449b9c r4f85b41  
    5050                "http://localhost:5173",
    5151                "http://127.0.0.1:5173"));
    52         config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
    53         config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
     52        config.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
     53        config.setAllowedHeaders(List.of("Authorization", "Content-Type", "Accept", "Origin", "X-Requested-With"));
     54        config.setAllowCredentials(true);
    5455
    5556        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  • frontend/src/App.jsx

    r8449b9c r4f85b41  
    1919import NewInvestment from "./pages/Dashboard/pages/Investing/NewInvestment.jsx";
    2020import Discipline from "./pages/Dashboard/pages/Discipline/Discipline.jsx";
     21import DisciplineTracking from "./pages/Dashboard/pages/Discipline/DisciplineTracking.jsx";
    2122
    2223function RequireAuth({ children }) {
     
    5960          <Route path="investing/assets/new" element={<NewInvestment />} />
    6061          <Route path="discipline" element={<Discipline />} />
     62           <Route path="discipline/tracking" element={<DisciplineTracking />} />
    6163        </Route>
    6264        <Route path="*" element={<Navigate to="/" replace />} />
  • frontend/src/pages/Dashboard/pages/Discipline/Discipline.jsx

    r8449b9c r4f85b41  
    1 import React from "react";
     1import React, { useEffect, useState } from "react";
     2import { useNavigate } from "react-router-dom";
    23
    3 const Discipline = () => {
     4import {
     5  getDisciplineStatus,
     6  startDisciplineTracking,
     7} from "../../../../api/discipline";
     8
     9import DisciplineCenteredCard from "./components/DisciplineCenteredCard.jsx";
     10import DisciplineStartCtaCard from "./components/DisciplineStartCtaCard.jsx";
     11
     12export 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
    474  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        />
    1182      </div>
    1283    </div>
    1384  );
    14 };
    15 
    16 export default Discipline;
     85}
Note: See TracChangeset for help on using the changeset viewer.