feat(events): add competitor number (bib) support
Allow participants to set their bib/competitor number per event. Display as badge next to username in participant lists. - Add competitorNumber field to EventParticipant model - Add PUT /events/:slug/competitor-number endpoint - Include competitorNumber in heats/me and heats/all responses - Add input field in HeatsBanner component - Display badge in UserListItem component - Add unit tests for competitor number feature
This commit is contained in:
@@ -43,7 +43,9 @@ const EventChatPage = () => {
|
||||
|
||||
// Heats state
|
||||
const [myHeats, setMyHeats] = useState([]);
|
||||
const [myCompetitorNumber, setMyCompetitorNumber] = useState(null);
|
||||
const [userHeats, setUserHeats] = useState(new Map());
|
||||
const [userCompetitorNumbers, setUserCompetitorNumbers] = useState(new Map());
|
||||
const [showHeatsBanner, setShowHeatsBanner] = useState(false);
|
||||
const [hideMyHeats, setHideMyHeats] = useState(false);
|
||||
const [showHeatsModal, setShowHeatsModal] = useState(false);
|
||||
@@ -87,18 +89,25 @@ const EventChatPage = () => {
|
||||
|
||||
const loadData = async () => {
|
||||
try {
|
||||
// Load my heats
|
||||
const myHeatsData = await heatsAPI.getMyHeats(slug);
|
||||
// Load my heats and competitor number
|
||||
const myHeatsResponse = await heatsAPI.getMyHeats(slug);
|
||||
const myHeatsData = myHeatsResponse.data || [];
|
||||
setMyHeats(myHeatsData);
|
||||
setMyCompetitorNumber(myHeatsResponse.competitorNumber);
|
||||
setShowHeatsBanner(myHeatsData.length === 0);
|
||||
|
||||
// Load all users' heats
|
||||
// Load all users' heats and competitor numbers
|
||||
const allHeatsData = await heatsAPI.getAllHeats(slug);
|
||||
const heatsMap = new Map();
|
||||
const competitorNumbersMap = new Map();
|
||||
allHeatsData.forEach((userHeat) => {
|
||||
heatsMap.set(userHeat.userId, userHeat.heats);
|
||||
if (userHeat.competitorNumber) {
|
||||
competitorNumbersMap.set(userHeat.userId, userHeat.competitorNumber);
|
||||
}
|
||||
});
|
||||
setUserHeats(heatsMap);
|
||||
setUserCompetitorNumbers(competitorNumbersMap);
|
||||
|
||||
// Load all checked-in users (participants)
|
||||
const eventDetails = await eventsAPI.getDetails(slug);
|
||||
@@ -384,6 +393,7 @@ const EventChatPage = () => {
|
||||
slug={slug}
|
||||
onSave={handleHeatsSave}
|
||||
onDismiss={() => setShowHeatsBanner(false)}
|
||||
existingCompetitorNumber={myCompetitorNumber}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -392,6 +402,7 @@ const EventChatPage = () => {
|
||||
users={getAllDisplayUsers().filter(u => !shouldHideUser(u.userId))}
|
||||
activeUsers={activeUsers}
|
||||
userHeats={userHeats}
|
||||
userCompetitorNumbers={userCompetitorNumbers}
|
||||
myHeats={myHeats}
|
||||
hideMyHeats={hideMyHeats}
|
||||
onHideMyHeatsChange={setHideMyHeats}
|
||||
@@ -457,6 +468,7 @@ const EventChatPage = () => {
|
||||
onSave={handleHeatsSave}
|
||||
onDismiss={() => setShowHeatsModal(false)}
|
||||
existingHeats={myHeats}
|
||||
existingCompetitorNumber={myCompetitorNumber}
|
||||
/>
|
||||
</Modal>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user