Skip to content

Commit 451f3bb

Browse files
authored
Merge branch 'dev' into formatting-fixes
2 parents 52d9227 + 50aeca1 commit 451f3bb

File tree

4 files changed

+75
-11
lines changed

4 files changed

+75
-11
lines changed

backend/resolvers/participantResolver.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,44 @@ const participantResolver = {
115115

116116
return result;
117117
},
118+
getWeeklyEarnings: async (
119+
_parent: undefined,
120+
{ participant_id }: { participant_id: number }
121+
): Promise<number[]> => {
122+
const today = new Date();
123+
const sevenDaysAgo = new Date();
124+
sevenDaysAgo.setDate(today.getDate() - 6);
125+
126+
const todayStr = today.toISOString().split("T")[0];
127+
const startStr = sevenDaysAgo.toISOString().split("T")[0];
128+
129+
const results = await prisma.$queryRaw<
130+
{ transaction_date: string; total: number }[]
131+
>`
132+
SELECT
133+
transaction_date,
134+
SUM(marillac_bucks) AS total
135+
FROM transaction
136+
WHERE participant_id = ${participant_id}
137+
AND transaction_type = 'EARNING'
138+
AND transaction_date >= ${startStr}
139+
AND transaction_date <= ${todayStr}
140+
GROUP BY transaction_date
141+
ORDER BY transaction_date ASC
142+
`;
143+
144+
const last7Days: string[] = Array.from({ length: 7 }, (_, i) => {
145+
const d = new Date();
146+
d.setDate(today.getDate() - (6 - i));
147+
return d.toISOString().split("T")[0];
148+
});
149+
150+
const earningsMap = Object.fromEntries(
151+
results.map((r) => [r.transaction_date, Number(r.total)])
152+
);
153+
154+
return last7Days.map((day) => earningsMap[day] || 0);
155+
},
118156
},
119157
Mutation: {
120158
createParticipant: async (

backend/types/resolvers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const resolvers = gql`
77
getParticipantByRoom(room_number: Int!): Participant
88
getParticipantsByRooms(room_numbers: [Int!]!): [Participant]
99
getParticipantById(participantId: Int!): Participant
10+
getWeeklyEarnings(participant_id: Int!): [Int!]!
1011
getGoalHistoryByParticipant(
1112
participant_id: Int!
1213
start_date: String

frontend/src/gql/queries.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,12 @@ export const GET_ASSIGNED_TASKS = gql`
352352
}
353353
`;
354354

355+
export const GET_WEEKLY_EARNINGS = gql`
356+
query GetWeeklyEarnings($participant_id: Int!) {
357+
getWeeklyEarnings(participant_id: $participant_id)
358+
}
359+
`;
360+
355361
export const GET_REPORT_RECIPIENTS = gql`
356362
query getReportRecipients {
357363
getReportRecipients {

frontend/src/participant/pages/progress/Main.tsx

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,63 @@ import { useQuery } from "@apollo/client";
33
import { ParticipantContext } from "../../common/ParticipantContext";
44
import { EditGoal } from "./components/EditGoal";
55
import { SetGoal } from "./components/SetGoal";
6-
import { GET_PARTICIPANT_BY_ID } from "../../../gql/queries";
6+
import {
7+
GET_PARTICIPANT_BY_ID,
8+
GET_WEEKLY_EARNINGS,
9+
} from "../../../gql/queries";
710
import WeeklyEarningsChart from "./components/EarningsWidget";
811
import BucksGoalCard from "./elements/BucksGoalCard";
912

1013
export default function ParticipantsProgressPage() {
1114
const [editGoal, setEditGoal] = useState(false);
1215
const [setGoal, setSetGoal] = useState(false);
1316
const participantContext = useContext(ParticipantContext);
14-
const sampleWeeklyEarnings = [10, 15, 8, 20, 12, 18, 35];
1517

16-
// Fetch participant data to get current goal
17-
const { data, loading, refetch } = useQuery(GET_PARTICIPANT_BY_ID, {
18+
// Fetch participant data
19+
const {
20+
data: participantData,
21+
loading: loadingParticipant,
22+
refetch: refetchParticipant,
23+
} = useQuery(GET_PARTICIPANT_BY_ID, {
1824
variables: { participantId: participantContext?.id },
1925
skip: !participantContext?.id,
2026
});
2127

22-
const participant = data?.getParticipantById;
28+
// Fetch earnings data
29+
const {
30+
data: earningsData,
31+
loading: loadingEarnings,
32+
refetch: refetchEarnings,
33+
} = useQuery(GET_WEEKLY_EARNINGS, {
34+
variables: { participant_id: participantContext?.id },
35+
skip: !participantContext?.id,
36+
});
37+
38+
const weeklyEarnings = earningsData?.getWeeklyEarnings || [
39+
0, 0, 0, 0, 0, 0, 0,
40+
];
41+
const participant = participantData?.getParticipantById;
2342
const currentGoal = participant?.marillac_bucks_goal;
2443
const currentBalance = participant?.marillac_bucks || 0;
2544

45+
const loading = loadingParticipant || loadingEarnings;
46+
2647
const handleClose = () => {
2748
setSetGoal(false);
2849
setEditGoal(false);
2950
};
3051

3152
const handleGoalSet = async () => {
32-
await refetch(); // Refresh data to show new goal
53+
await refetchParticipant();
3354
handleClose();
3455
};
3556

3657
const handleGoalUpdated = async () => {
37-
await refetch(); // Refresh data to show updated goal
58+
await refetchParticipant();
3859
handleClose();
3960
};
40-
41-
// Don't render goal section until data is loaded to avoid flickering
4261
if (loading) {
43-
return null; // or return a loading spinner if preferred
62+
return null;
4463
}
4564

4665
const handleGoalClick = () => {
@@ -70,7 +89,7 @@ export default function ParticipantsProgressPage() {
7089
/>
7190
)}
7291
<div style={{ padding: "10px 20px" }}>
73-
<WeeklyEarningsChart weeklyEarnings={sampleWeeklyEarnings} />
92+
<WeeklyEarningsChart weeklyEarnings={weeklyEarnings} />
7493
</div>
7594
</>
7695
);

0 commit comments

Comments
 (0)