diff --git a/src/app/(private)/hangouts/_components/HangoutList.tsx b/src/app/(private)/hangouts/_components/HangoutList.tsx index c08b889..c65d7bb 100644 --- a/src/app/(private)/hangouts/_components/HangoutList.tsx +++ b/src/app/(private)/hangouts/_components/HangoutList.tsx @@ -1,8 +1,11 @@ "use client"; -import React, { useState } from "react"; + +import React, { useState, useEffect } from "react"; import HangoutActionButton from "./HangoutActionButton"; import ConfirmLocationModal from "../_components/FinalConfirmationModal"; +import HangoutProgressBar from "./HangoutProgressBar"; import { Participant } from "./Hangouts"; +import { getApiBase } from "@/utils/etc/apiBase"; interface HangoutListProps { name: string; @@ -15,6 +18,17 @@ interface HangoutListProps { participants: Participant[]; } +const flowStatusIndexMap: Record = { + "pending-time-input": 0, + "pending-time-vote": 1, + "pending-confirm-time": 2, + "pending-location-vote": 3, + "pending-confirm-location": 4, + "accepted-final-confirmation": 5, +}; + +const knownStages = Object.keys(flowStatusIndexMap); + export default function HangoutList({ name, id, @@ -25,8 +39,38 @@ export default function HangoutList({ flowStatus, participants, }: HangoutListProps) { - const [isConfirmationModal, setIsConfirmationModal] = - useState(false); + const [isConfirmationModal, setIsConfirmationModal] = useState(false); + const [progress, setProgress] = useState<{ + currentStageIndex: number; + completed: number; + total: number; + } | null>(null); + + useEffect(() => { + async function fetchHangoutProgress() { + try { + const res = await fetch(`${getApiBase()}/get_hangout_progress/${id}`); + const data = await res.json(); + + if (data.status === 200) { + const stageKey = data.current_stage; + if (knownStages.includes(stageKey)) { + setProgress(prev => ({ + currentStageIndex: flowStatusIndexMap[stageKey], + completed: data.stage_count, + total: data.total_count, + })); + } else { + setProgress(prev => prev ?? null); + } + } + } catch (err) { + console.error("Failed to fetch hangout progress:", err); + } + } + + fetchHangoutProgress(); + }, [id]); return ( <> @@ -50,6 +94,16 @@ export default function HangoutList({ + {progress && ( + + )} +
diff --git a/src/app/(private)/hangouts/_components/HangoutProgressBar.tsx b/src/app/(private)/hangouts/_components/HangoutProgressBar.tsx new file mode 100644 index 0000000..c750c28 --- /dev/null +++ b/src/app/(private)/hangouts/_components/HangoutProgressBar.tsx @@ -0,0 +1,57 @@ +import React from "react"; + +interface HangoutProgressBarProps { + currentStageIndex: number; + completed: number; + total: number; + stages: number; + flowStatus: string; +} + +const stageLabels = [ + "Submit Availability", // 0 + "Vote on Availability", // 1 + "Confirm Details", // 2 + "Vote on Location", // 2 + "Confirm Location", // 3 + "Hangout Scheduled" // 4 +]; + +export default function HangoutProgressBar({ + currentStageIndex, + completed, + total, + stages, + flowStatus, +}: HangoutProgressBarProps) { + const label = + flowStatus === "pending-confirm-details" + ? "Confirm Details" + : stageLabels[currentStageIndex] ?? "Progress"; + + const showRemaining = + currentStageIndex !== stageLabels.length - 1 && total - completed > 0; + + return ( +
+ + {label} + {showRemaining && <> • {total - completed} remaining} + +
+ {Array.from({ length: stages }).map((_, i) => ( +
+ ))} +
+
+ ); +} diff --git a/src/utils/etc/informationStrings.ts b/src/utils/etc/informationStrings.ts index 02b9f4e..abbf02d 100644 --- a/src/utils/etc/informationStrings.ts +++ b/src/utils/etc/informationStrings.ts @@ -2,7 +2,7 @@ export const informationStrings = { startHangout: "Start a new Hangout by giving it a title and inviting your friends. ", hangouts: - "View and manage all your hangouts here.\nEach hangout shows its current status, and available action buttons will appear depending on the stage.", + " View and manage all your hangouts here.\n Each hangout shows its current status, and available action buttons will appear depending on the stage.\n----------------------\nA progress bar visually tracks the hangout’s flow through four key stages:\n1. Submit Availability – attendees share their available times.\n2. Vote on Availability – attendees vote on the best time options.\n3. Vote on Location – attendees vote on where to meet.\n4. Confirm Location – final confirmation of the meeting place and time.\n----------------------\n The bar will also show how many members have completed the current stage before going onto the next.", availabilityInput: "Add all the dates and times you are available. These will become the options that attendees vote on.\nThe more options you provide, the easier it will be to find a time that works for everyone!", availabilityVoting: