Skip to content

Commit 0203908

Browse files
authored
Merge pull request #270 from chingu-x/dev
1.0.0-alpha.6
2 parents 13d2836 + 2169bc2 commit 0203908

18 files changed

+167
-74
lines changed

CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/).
77

8+
9+
## [1.0.0-alpha.6] - 2024-09-27
10+
11+
### Added
12+
- Added po and sm forms for the weekly checkin for the appropriate teams https://github.com/chingu-x/chingu-dashboard/issues/216
13+
14+
### Changed
15+
- Changed how we're accessing meeting data to match changes in backend https://github.com/chingu-x/chingu-dashboard/pull/269
16+
- Updated dropdown menu in top nav https://github.com/chingu-x/chingu-dashboard/issues/261
17+
18+
19+
### Fixed
20+
821
## [1.0.0-alpha.5] - 2024-09-19
922

1023
### Added

src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ export const getDashboardData = async (
200200
.map((sprint) =>
201201
fetchMeeting({
202202
sprintNumber: sprint.number,
203-
meetingId: sprint.teamMeetings[0]?.id,
203+
meetingId: sprint.teamMeetings[0],
204204
}),
205205
);
206206

src/app/(main)/my-voyage/[teamId]/sprints/components/EmptySprintWrapper.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import ErrorComponent from "@/components/Error";
2424
function getMeeting(sprints: Sprint[], sprintNumber: number) {
2525
const sprint = sprints.find((sprint) => sprint.number === sprintNumber);
2626

27-
if (sprint?.teamMeetings && sprint?.teamMeetings.length > 0)
28-
return sprint.teamMeetings[0];
27+
if (sprint?.teamMeetingsData && sprint?.teamMeetingsData.length > 0)
28+
return sprint.teamMeetingsData[0];
2929
return null;
3030
}
3131

src/app/(main)/my-voyage/[teamId]/sprints/components/ProgressStepper.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export default function ProgressStepper({
3131

3232
function handleClick(sprintNumber: number) {
3333
const meetingId = sprints.find((sprint) => sprint.number === sprintNumber)!
34-
.teamMeetings[0]?.id;
34+
.teamMeetings[0];
3535

3636
if (meetingId) {
3737
router.push(

src/app/(main)/my-voyage/[teamId]/sprints/components/RedirectToCurrentSprintWrapper.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export default async function RedirectToCurrentSprintWrapper({
5151
const teamId = Number(params.teamId);
5252

5353
let currentSprintNumber: number;
54-
let currentMeetingId: number;
5554

5655
const [user, error] = await getUser();
5756

@@ -110,12 +109,12 @@ export default async function RedirectToCurrentSprintWrapper({
110109
);
111110
}
112111
const { teamMeetings, number } = getCurrentSprint(res!.sprints) as Sprint;
112+
113113
currentSprintNumber = number;
114-
currentMeetingId = teamMeetings[0]?.id;
115114

116-
if (currentMeetingId) {
115+
if (teamMeetings.length !== 0) {
117116
redirect(
118-
`/my-voyage/${teamId}/sprints/${currentSprintNumber}/meeting/${currentMeetingId}`,
117+
`/my-voyage/${teamId}/sprints/${currentSprintNumber}/meeting/${teamMeetings[0]}`,
119118
);
120119
} else {
121120
redirect(`/my-voyage/${teamId}/sprints/${currentSprintNumber}`);

src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export default async function SprintWrapper({ params }: SprintWrapperProps) {
125125

126126
const correspondingMeetingId = voyageData.sprints.find(
127127
(sprint) => sprint.number === sprintNumber,
128-
)?.teamMeetings[0]?.id;
128+
)?.teamMeetings[0];
129129

130130
if (meetingId === correspondingMeetingId) {
131131
const [res, error] = await fetchMeeting({ sprintNumber, meetingId });

src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx

+67-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { CacheTag } from "@/utils/cacheTag";
1212
import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync";
1313
import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData";
1414
import routePaths from "@/utils/routePaths";
15-
import { Forms } from "@/utils/form/formsEnums";
15+
import { Forms, UserRole } from "@/utils/form/formsEnums";
1616
import { type Question, type TeamMemberForCheckbox } from "@/utils/form/types";
1717
import { getSprintCheckinIsStatus } from "@/utils/getFormStatus";
1818
import { getCurrentSprint } from "@/utils/getCurrentSprint";
@@ -75,6 +75,11 @@ export default async function WeeklyCheckInWrapper({
7575
let description = "";
7676
let questions = [] as Question[];
7777

78+
let hasProductOwner = false;
79+
let hasScrumMaster = false;
80+
let isScrumMaster = false;
81+
let isProductOwner = false;
82+
7883
const [user, error] = await getUser();
7984

8085
const { errorResponse, data } = await getCurrentVoyageData({
@@ -141,6 +146,25 @@ export default async function WeeklyCheckInWrapper({
141146
}).voyageTeamMemberId;
142147
}
143148

149+
// Check if a team has a product owner or a scrum muster and if a user is a team has a product owner or a scrum muster
150+
hasScrumMaster = !!res.voyageTeamMembers.find(
151+
(member) =>
152+
member.voyageRole.name === UserRole.scrumMaster.toString(),
153+
);
154+
155+
hasProductOwner = !!res.voyageTeamMembers.find(
156+
(member) =>
157+
member.voyageRole.name === UserRole.productOwner.toString(),
158+
);
159+
160+
const currentUserRole = res.voyageTeamMembers.find(
161+
(member) => member.id === voyageTeamMemberId,
162+
)?.voyageRole.name;
163+
164+
isScrumMaster = currentUserRole === UserRole.scrumMaster.toString();
165+
166+
isProductOwner = currentUserRole === UserRole.productOwner.toString();
167+
144168
// Get all teamMembers except for the current user
145169
if (voyageTeamMemberId) {
146170
teamMembers = res.voyageTeamMembers
@@ -163,7 +187,7 @@ export default async function WeeklyCheckInWrapper({
163187
);
164188
}
165189

166-
// Fetch form
190+
// Fetch general checkin form
167191
const [formRes, formError] = await fetchFormQuestions({
168192
formId: Forms.checkIn,
169193
});
@@ -176,8 +200,49 @@ export default async function WeeklyCheckInWrapper({
176200
/>
177201
);
178202
}
203+
179204
if (formRes && formRes?.description) description = formRes.description;
180205
if (formRes && formRes?.questions) questions = formRes.questions;
206+
207+
// Fetch PO checkin questions (form)
208+
if (hasProductOwner && !isProductOwner) {
209+
const [POformRes, POformError] = await fetchFormQuestions({
210+
formId: Forms.checkinPO,
211+
});
212+
213+
if (POformError) {
214+
return (
215+
<ErrorComponent
216+
errorType={ErrorType.FETCH_FORM_QUESTIONS}
217+
message={POformError.message}
218+
/>
219+
);
220+
}
221+
222+
if (POformRes && POformRes?.questions)
223+
questions = [...questions, ...POformRes.questions];
224+
}
225+
226+
// Fetch SM checkin questions (form)
227+
if (hasScrumMaster && !isScrumMaster) {
228+
const [SMformRes, SMformError] = await fetchFormQuestions({
229+
formId: Forms.checkinSM,
230+
});
231+
232+
if (SMformError) {
233+
return (
234+
<ErrorComponent
235+
errorType={ErrorType.FETCH_FORM_QUESTIONS}
236+
message={SMformError.message}
237+
/>
238+
);
239+
}
240+
241+
if (SMformRes && SMformRes?.questions)
242+
questions = [...questions, ...SMformRes.questions];
243+
}
244+
245+
questions = questions.sort((a, b) => a.order - b.order);
181246
}
182247
} else {
183248
redirect(routePaths.dashboardPage());

src/app/(main)/my-voyage/[teamId]/sprints/components/forms/AgendaTopicForm.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,13 @@ export default function AgendaTopicForm() {
160160

161161
useEffect(() => {
162162
if (sprintNumber && agendaId) {
163-
const topic = sprints
164-
.find((sprint) => sprint.number === sprintNumber)
165-
?.teamMeetings[0].agendas?.find((topic) => topic.id === agendaId);
163+
const sprint = sprints.find((sprint) => sprint.number === sprintNumber);
164+
165+
const topic =
166+
sprint?.teamMeetingsData &&
167+
sprint.teamMeetingsData[0].agendas?.find(
168+
(topic) => topic.id === agendaId,
169+
);
166170

167171
setTopicData(topic);
168172
setEditMode(true);

src/app/(main)/my-voyage/[teamId]/sprints/components/forms/MeetingForm.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,10 @@ export default function MeetingForm() {
177177
useEffect(() => {
178178
if (params.meetingId) {
179179
const meeting = sprints.find(
180-
(sprint) => sprint.teamMeetings[0]?.id === +params.meetingId,
181-
)?.teamMeetings[0];
180+
(sprint) =>
181+
sprint.teamMeetingsData &&
182+
sprint.teamMeetingsData[0].id === +params.meetingId,
183+
);
182184

183185
setMeetingData(meeting as Meeting);
184186
setEditMode(true);

src/app/(main)/my-voyage/[teamId]/sprints/components/sections/Notes.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ export default function Notes() {
4343
} = useSprint();
4444

4545
useEffect(() => {
46-
setData(sprints[sprintNumber - 1].teamMeetings[0].notes);
46+
const sprint = sprints[sprintNumber - 1];
47+
if (sprint.teamMeetingsData && sprint.teamMeetingsData.length) {
48+
setData(sprint.teamMeetingsData[0].notes);
49+
}
4750
}, [sprints, sprintNumber]);
4851

4952
const {

src/app/(main)/my-voyage/[teamId]/sprints/components/sections/Planning.tsx

+8-5
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,14 @@ export default function Planning() {
5252
} = useSprint();
5353

5454
useEffect(() => {
55-
setData(
56-
sprints[sprintNumber - 1].teamMeetings[0].formResponseMeeting?.find(
57-
(form) => form.form.id === Number(Forms.planning),
58-
),
59-
);
55+
const sprint = sprints[sprintNumber - 1];
56+
if (sprint.teamMeetingsData && sprint.teamMeetingsData.length) {
57+
setData(
58+
sprint.teamMeetingsData[0].formResponseMeeting?.find(
59+
(form) => form.form.id === Number(Forms.planning),
60+
),
61+
);
62+
}
6063
}, [sprints, sprintNumber]);
6164

6265
const goal = data?.responseGroup.responses.find(

src/app/(main)/my-voyage/[teamId]/sprints/components/sections/Review.tsx

+8-5
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,14 @@ export default function Review() {
5656
} = useSprint();
5757

5858
useEffect(() => {
59-
setData(
60-
sprints[sprintNumber - 1].teamMeetings[0].formResponseMeeting?.find(
61-
(form) => form.form.id === Number(Forms.review),
62-
),
63-
);
59+
const sprint = sprints[sprintNumber - 1];
60+
if (sprint.teamMeetingsData && sprint.teamMeetingsData.length) {
61+
setData(
62+
sprint.teamMeetingsData[0].formResponseMeeting?.find(
63+
(form) => form.form.id === Number(Forms.review),
64+
),
65+
);
66+
}
6467
}, [sprints, sprintNumber]);
6568

6669
const what_right = data?.responseGroup.responses.find(

src/app/(main)/my-voyage/[teamId]/sprints/sprintsService.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export interface SprintsResponse {
9595
number: number;
9696
startDate: string;
9797
endDate: string;
98-
teamMeetings: { id: number }[];
98+
teamMeetings: number[];
9999
}[];
100100
}
101101

src/components/navbar/DropDown.tsx

+33-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use client";
22

33
import { ChevronDownIcon } from "@heroicons/react/24/outline";
4-
import DropDownLink from "./DropDownLink";
4+
import Link from "next/link";
55
import Button from "@/components/Button";
66
import { useAppDispatch, useUser } from "@/store/hooks";
77
import { clientSignOut } from "@/store/features/auth/authSlice";
@@ -14,12 +14,18 @@ export default function DropDown({ openState }: { openState?: boolean }) {
1414
const activeVoyage = allVoyages?.find(
1515
(item) => item.voyageTeam.voyage.status.name === "Active",
1616
);
17-
const currentVoyage =
18-
activeVoyage?.voyageTeam.name ??
19-
"Please join a voyage to see your status information.";
17+
18+
const currentVoyage = activeVoyage?.voyageTeam.name
19+
? `Team - Tier ${activeVoyage.voyageTeam.name
20+
.split("-")[1]
21+
.split("tier")[1]
22+
.toUpperCase()} ${activeVoyage.voyageTeam.name
23+
.split("-")[0]
24+
.toUpperCase()}`
25+
: "Please join a voyage to see your status information.";
2026
const closed = "hidden";
2127
const open =
22-
"absolute z-[1] w-44 p-4 [&>*]:mt-2 mt-6 shadow bg-base-100 right-0 border border-neutral rounded-2xl";
28+
"absolute flex flex-col gap-5 z-[1] w-[250px] p-5 bottom-100 translate-y-[15%] shadow-md bg-base-200 right-0 border border-base-100 rounded-2xl";
2329

2430
async function handleClick() {
2531
const [res, error] = await serverSignOut();
@@ -35,7 +41,7 @@ export default function DropDown({ openState }: { openState?: boolean }) {
3541
}
3642
}
3743

38-
const handleDropDownClick = (event: React.MouseEvent<HTMLUListElement>) => {
44+
const handleDropDownClick = (event: React.MouseEvent<HTMLDivElement>) => {
3945
event.stopPropagation();
4046
};
4147

@@ -47,35 +53,45 @@ export default function DropDown({ openState }: { openState?: boolean }) {
4753
>
4854
<ChevronDownIcon className="w-4 cursor-pointer text-base-300" />
4955
</label>
50-
<ul
56+
<div
5157
tabIndex={0}
5258
className={openState ? open : closed}
5359
onClick={handleDropDownClick}
5460
>
55-
<li className="rounded-lg bg-secondary-content p-2 text-xs [&>*]:m-1">
56-
<p className="text-xs text-neutral">My Status:</p>
57-
{currentVoyage ? (
58-
<p className="border border-transparent font-semibold text-base-300">
61+
<div className="rounded-lg bg-secondary-content p-2 text-xs [&>*]:m-1">
62+
<p className="text-[10px] font-medium text-neutral-focus">
63+
My Voyage:
64+
</p>
65+
{activeVoyage?.voyageTeam.name ? (
66+
<p className="border border-transparent text-base font-medium text-base-300">
5967
{currentVoyage}
6068
</p>
6169
) : (
6270
<p className="border-transparent font-semibold text-base-300">
6371
{currentVoyage}
6472
</p>
6573
)}
66-
</li>
67-
<DropDownLink title="Settings" href="/hello404" />
74+
</div>
75+
<Link href="/hello404">
76+
<Button
77+
type="button"
78+
variant="link"
79+
size="lg"
80+
className="m-0 flex w-full justify-start p-2 hover:bg-base-100 hover:text-base-300"
81+
>
82+
Settings
83+
</Button>
84+
</Link>
6885
<Button
69-
title="signout"
7086
type="button"
7187
onClick={handleClick}
7288
variant="link"
73-
size={"lg"}
74-
className="m-0 flex w-full justify-start p-2 hover:bg-neutral-content hover:text-base-300"
89+
size="lg"
90+
className="m-0 flex w-full justify-start p-2 hover:bg-base-100 hover:text-base-300"
7591
>
7692
Sign Out
7793
</Button>
78-
</ul>
94+
</div>
7995
</div>
8096
);
8197
}

src/components/navbar/DropDownLink.tsx

-19
This file was deleted.

0 commit comments

Comments
 (0)