Skip to content

Commit

Permalink
Merge pull request #136 from chingu-x/feature/sprints-functionality-pt4
Browse files Browse the repository at this point in the history
Feature/sprints functionality pt4
  • Loading branch information
Dan-Y-Ko authored Jun 7, 2024
2 parents 1091c1a + f0d31ac commit 8f52e9c
Show file tree
Hide file tree
Showing 53 changed files with 1,482 additions and 986 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Button from "@/components/Button";
import TextInput from "@/components/inputs/TextInput";
import { onOpenModal } from "@/store/features/modal/modalSlice";
import { useAppDispatch } from "@/store/hooks";
import { validateTextInput } from "@/helpers/form/validateInput";
import { validateTextInput } from "@/utils/form/validateInput";
import routePaths from "@/utils/routePaths";
import useServerAction from "@/hooks/useServerAction";
import Spinner from "@/components/Spinner";
Expand Down
2 changes: 1 addition & 1 deletion src/app/(auth)/sign-in/components/SignInFormContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { serverSignIn } from "@/app/(auth)/authService";

import Button from "@/components/Button";
import TextInput from "@/components/inputs/TextInput";
import { validateTextInput } from "@/helpers/form/validateInput";
import { validateTextInput } from "@/utils/form/validateInput";
import { clientSignIn } from "@/store/features/auth/authSlice";
import { onOpenModal } from "@/store/features/modal/modalSlice";
import { useAppDispatch } from "@/store/hooks";
Expand Down
2 changes: 1 addition & 1 deletion src/app/(auth)/sign-up/components/SignUpFormContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import Button from "@/components/Button";
import TextInput from "@/components/inputs/TextInput";
import { validateTextInput } from "@/helpers/form/validateInput";
import { validateTextInput } from "@/utils/form/validateInput";
import routePaths from "@/utils/routePaths";

const validationSchema = z.object({
Expand Down
2 changes: 1 addition & 1 deletion src/app/(auth)/users/components/NewPasswordContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import TextInput from "@/components/inputs/TextInput";
import Button from "@/components/Button";
import { onOpenModal } from "@/store/features/modal/modalSlice";
import { useAppDispatch } from "@/store/hooks";
import { validateTextInput } from "@/helpers/form/validateInput";
import { validateTextInput } from "@/utils/form/validateInput";
import useServerAction from "@/hooks/useServerAction";
import Spinner from "@/components/Spinner";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useParams } from "next/navigation";
import { PencilSquareIcon } from "@heroicons/react/24/outline";
import { type SetStateAction, useEffect } from "react";
import TextInput from "@/components/inputs/TextInput";
import { validateTextInput } from "@/helpers/form/validateInput";
import { validateTextInput } from "@/utils/form/validateInput";
import { useAppDispatch } from "@/store/hooks";
import { editHours } from "@/app/(main)/my-voyage/[teamId]/directory/directoryService";
import { onOpenModal } from "@/store/features/modal/modalSlice";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { type Dispatch, type SetStateAction, useEffect } from "react";
import { useParams } from "next/navigation";
import Button from "@/components/Button";
import TextInput from "@/components/inputs/TextInput";
import { validateTextInput } from "@/helpers/form/validateInput";
import { validateTextInput } from "@/utils/form/validateInput";
import { useAppDispatch } from "@/store/hooks";
import useServerAction from "@/hooks/useServerAction";
import { addFeature } from "@/myVoyage/features/featuresService";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { type SubmitHandler, useForm } from "react-hook-form";
import { useEffect, useRef, useState } from "react";
import Card from "./Card";
import TextInput from "@/components/inputs/TextInput";
import { validateTextInput } from "@/helpers/form/validateInput";
import { validateTextInput } from "@/utils/form/validateInput";
import { type Features } from "@/store/features/features/featuresSlice";
import useServerAction from "@/hooks/useServerAction";
import { editFeature } from "@/myVoyage/features/featuresService";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useState, useEffect } from "react";
import Button from "@/components/Button";
import TextInput from "@/components/inputs/TextInput";
import Textarea from "@/components/inputs/Textarea";
import { validateTextInput } from "@/helpers/form/validateInput";
import { validateTextInput } from "@/utils/form/validateInput";
import { useAppDispatch, useIdeation } from "@/store/hooks";
import { type IdeationData } from "@/store/features/ideation/ideationSlice";
import Spinner from "@/components/Spinner";
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Suspense } from "react";

import WeeklyCheckInWrapper from "@/myVoyage/sprints/components/WeeklyCheckInWrapper";
import Spinner from "@/components/Spinner";

interface WeeklyCheckInPageProps {
params: {
teamId: string;
meetingId: string;
sprintNumber: string;
};
}

export default function WeeklyCheckInPage({ params }: WeeklyCheckInPageProps) {
return (
<Suspense fallback={<Spinner />}>
<WeeklyCheckInWrapper params={params} />
</Suspense>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Suspense } from "react";

import SubmitProjectWrapper from "@/myVoyage/sprints/components/SubmitProjectWrapper";
import Spinner from "@/components/Spinner";

interface VoyageSubmissionPageProps {
params: {
teamId: string;
meetingId: string;
sprintNumber: string;
};
}

export default function VoyageSubmissionPage({
params,
}: VoyageSubmissionPageProps) {
return (
<Suspense fallback={<Spinner />}>
<SubmitProjectWrapper params={params} />
</Suspense>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import { type Voyage, type Sprint } from "@/store/features/sprint/sprintSlice";
import { getUser } from "@/utils/getUser";
import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData";
import routePaths from "@/utils/routePaths";
import {
getSprintCheckinIsStatus,
getVoyageProjectStatus,
} from "@/utils/getFormStatus";

function getMeeting(sprints: Sprint[], sprintNumber: number) {
const sprint = sprints.find((sprint) => sprint.number === sprintNumber);
Expand Down Expand Up @@ -79,6 +83,15 @@ export default async function EmptySprintWrapper({
`/my-voyage/${teamId}/sprints/${sprintNumber}/meeting/${meeting.id}`,
);
} else {
// Check if a checkin form for the current sprint has been submitted
const sprintCheckinIsSubmitted = getSprintCheckinIsStatus(
user,
sprintNumber,
);

// Check if a voyage project has been submitted
const voyageProjectIsSubmitted = getVoyageProjectStatus(user, teamId);

return (
<div className="flex w-full flex-col gap-y-10">
<VoyagePageBannerContainer
Expand All @@ -94,7 +107,12 @@ export default async function EmptySprintWrapper({
/>
</VoyagePageBannerContainer>
<ProgressStepper currentSprintNumber={currentSprintNumber} />
<SprintActions params={params} />
<SprintActions
params={params}
sprintCheckinIsSubmitted={sprintCheckinIsSubmitted}
voyageProjectIsSubmitted={voyageProjectIsSubmitted}
currentSprintNumber={currentSprintNumber}
/>
<EmptySprintState />
<EmptySprintProvider voyage={voyageData} />
</div>
Expand Down
126 changes: 93 additions & 33 deletions src/app/(main)/my-voyage/[teamId]/sprints/components/SprintActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import {
ArrowRightIcon,
PlusIcon,
} from "@heroicons/react/24/outline";
import {
CheckCircleIcon,
RocketLaunchIcon as SolidRocketLaunchIcon,
} from "@heroicons/react/24/solid";

import Button from "@/components/Button";
import routePaths from "@/utils/routePaths";
Expand All @@ -16,53 +20,109 @@ interface SprintActionsProps {
meetingId?: string;
sprintNumber: string;
};
sprintCheckinIsSubmitted: boolean;
voyageProjectIsSubmitted: boolean;
currentSprintNumber: number;
}

export default function SprintActions({ params }: SprintActionsProps) {
export default function SprintActions({
params,
sprintCheckinIsSubmitted,
voyageProjectIsSubmitted,
currentSprintNumber,
}: SprintActionsProps) {
const [teamId, meetingId, sprintNumber] = [
params.teamId,
params.meetingId,
params.sprintNumber,
];

const isCurrentSprint = sprintNumber === currentSprintNumber.toString();
const submitVoyageIsAllowed = sprintNumber === "5" || sprintNumber === "6";
return (
<div className="flex justify-between rounded-2xl border border-base-100 bg-base-200 p-5 shadow-md">
{/* TODO: add animated variant to Button.tsx ??? */}
<Link
href={
meetingId
? routePaths.submitVoyagePage(teamId, sprintNumber, meetingId)
: routePaths.dashboardPage()
}
>

function renderWeeklyCheckinButton() {
if (sprintCheckinIsSubmitted) {
return (
<Button variant="primary" size="lg" className="group" disabled={true}>
<CheckCircleIcon className="h-[18px] w-[18px]" />
Check-in Submitted
</Button>
);
} else {
if (isCurrentSprint) {
return (
<Button
variant="primary"
size="lg"
className="group"
disabled={false}
>
<DocumentCheckIcon className="h-[18px] w-[18px]" />
Submit Check-in
<ArrowRightIcon className="h-[18px] w-0 transition-all group-hover:w-[18px]" />
</Button>
);
} else {
return (
<Button variant="primary" size="lg" className="group" disabled={true}>
<DocumentCheckIcon className="h-[18px] w-[18px]" />
Submit Check-in
</Button>
);
}
}
}

function renderSubmitVoyageButton() {
if (submitVoyageIsAllowed) {
return (
<Button
variant="secondary"
size="lg"
className="group"
disabled={!meetingId || !submitVoyageIsAllowed}
disabled={false}
>
<RocketLaunchIcon className="h-[18px] w-[18px]" /> Submit Voyage
{(submitVoyageIsAllowed || !meetingId) && (
<ArrowRightIcon className="h-[18px] w-0 transition-all group-hover:w-[18px] group-disabled:group-hover:w-0" />
)}
<RocketLaunchIcon className="h-[18px] w-[18px]" />
Submit Voyage
<ArrowRightIcon className="h-[18px] w-0 transition-all group-hover:w-[18px]" />
</Button>
);
} else {
if (voyageProjectIsSubmitted) {
return (
<Button
variant="secondary"
size="lg"
className="group"
disabled={true}
>
<RocketLaunchIcon className="h-[18px] w-[18px]" />
Voyage Submitted
</Button>
);
} else {
return (
<Button
variant="secondary"
size="lg"
className="group"
disabled={true}
>
<SolidRocketLaunchIcon className="h-[18px] w-[18px]" />
Submit Voyage
</Button>
);
}
}
}

return (
<div className="flex justify-between rounded-2xl border border-base-100 bg-base-200 p-5 shadow-md">
<Link href={routePaths.submitVoyagePage(teamId, sprintNumber)}>
{renderSubmitVoyageButton()}
</Link>
<Link
href={
meetingId
? routePaths.weeklyCheckInPage(teamId, sprintNumber, meetingId)
: routePaths.dashboardPage()
}
>
<Button
variant="primary"
size="lg"
className="group"
disabled={!meetingId}
>
<DocumentCheckIcon className="h-[18px] w-[18px]" /> Submit Check-in
<ArrowRightIcon className="h-[18px] w-0 transition-all group-hover:w-[18px] group-disabled:group-hover:w-0" />
</Button>
<Link href={routePaths.weeklyCheckInPage(teamId, sprintNumber)}>
{renderWeeklyCheckinButton()}
</Link>
<Link
href={
Expand All @@ -72,7 +132,7 @@ export default function SprintActions({ params }: SprintActionsProps) {
}
>
<Button variant="outline" size="lg" className="group">
<CalendarIcon className="h-[18px] w-[18px]" />{" "}
<CalendarIcon className="h-[18px] w-[18px]" />
{meetingId ? "Edit Meeting" : "Create Meeting"}
{meetingId ? null : (
<PlusIcon className="h-[18px] w-0 transition-all group-hover:w-[18px]" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ import { getUser } from "@/utils/getUser";
import { getSprintCache } from "@/utils/getSprintCache";
import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData";
import routePaths from "@/utils/routePaths";
import { SprintSections } from "@/utils/sections";
import { Forms } from "@/utils/form/formsEnums";
import {
getSprintCheckinIsStatus,
getVoyageProjectStatus,
} from "@/utils/getFormStatus";

export async function fetchMeeting({
sprintNumber,
Expand Down Expand Up @@ -123,6 +127,12 @@ export default async function SprintWrapper({ params }: SprintWrapperProps) {
redirect(`/my-voyage/${teamId}/sprints/${currentSprintNumber}/`);
}

// Check if a checkin form for the current sprint has been submitted
const sprintCheckinIsSubmitted = getSprintCheckinIsStatus(user, sprintNumber);

// Check if a voyage project has been submitted
const voyageProjectIsSubmitted = getVoyageProjectStatus(user, teamId);

return (
<div className="flex w-full flex-col gap-y-10">
<VoyagePageBannerContainer
Expand All @@ -139,7 +149,12 @@ export default async function SprintWrapper({ params }: SprintWrapperProps) {
</VoyagePageBannerContainer>

<ProgressStepper currentSprintNumber={currentSprintNumber} />
<SprintActions params={params} />
<SprintActions
params={params}
sprintCheckinIsSubmitted={sprintCheckinIsSubmitted}
voyageProjectIsSubmitted={voyageProjectIsSubmitted}
currentSprintNumber={currentSprintNumber}
/>
<MeetingOverview
title={meetingData.title!}
dateTime={meetingData.dateTime!}
Expand All @@ -152,10 +167,10 @@ export default async function SprintWrapper({ params }: SprintWrapperProps) {
params={params}
notes={meetingData.notes}
planning={sectionsData.find(
(section) => section.form.id === Number(SprintSections.planning),
(section) => section.form.id === Number(Forms.planning),
)}
review={sectionsData.find(
(section) => section.form.id === Number(SprintSections.review),
(section) => section.form.id === Number(Forms.review),
)}
/>
</div>
Expand Down
Loading

0 comments on commit 8f52e9c

Please sign in to comment.