diff --git a/src/app/(main)/projects/create/page.tsx b/src/app/(main)/projects/create/page.tsx index 0679d1f..c737430 100644 --- a/src/app/(main)/projects/create/page.tsx +++ b/src/app/(main)/projects/create/page.tsx @@ -1,4 +1,5 @@ import { fetchProjectCategories } from "@/app/api/projects"; +import { preloadStaff } from "@/app/api/staff"; import { fetchAllTasks, fetchTaskTemplates } from "@/app/api/tasks"; import CreateProject from "@/components/CreateProject"; import { I18nProvider, getServerI18n } from "@/i18n"; @@ -16,6 +17,7 @@ const Projects: React.FC = async () => { fetchAllTasks(); fetchTaskTemplates(); fetchProjectCategories(); + preloadStaff(); return ( <> diff --git a/src/app/api/projects/actions.ts b/src/app/api/projects/actions.ts index d8106d2..90894fd 100644 --- a/src/app/api/projects/actions.ts +++ b/src/app/api/projects/actions.ts @@ -10,6 +10,7 @@ export interface CreateProjectInputs { projectName: string; projectCategoryId: number; projectDescription: string; + projectLeadId: number; // Client details clientCode: string; @@ -37,6 +38,9 @@ export interface CreateProjectInputs { payments: PaymentInputs[]; }; }; + + // Miscellaneous + expectedProjectFee: string; } export interface ManhourAllocation { diff --git a/src/app/api/projects/index.ts b/src/app/api/projects/index.ts index 2fdb597..7664ecb 100644 --- a/src/app/api/projects/index.ts +++ b/src/app/api/projects/index.ts @@ -1,18 +1,34 @@ +import { serverFetchJson } from "@/app/utils/fetchUtil"; +import { BASE_API_URL } from "@/config/api"; import { cache } from "react"; import "server-only"; +import { Staff } from "../staff"; + +interface Project { + id: number; + code: string; + name: string; + projectCategory: { + name: string; + }; + teamLead: Staff; + customer: { + name: string; + }; +} export interface ProjectResult { id: number; code: string; name: string; - category: "Confirmed Project" | "Project to be bidded"; + category: string; team: string; client: string; } export interface ProjectCategory { id: number; - label: string; + name: string; } export const preloadProjects = () => { @@ -21,18 +37,35 @@ export const preloadProjects = () => { }; export const fetchProjects = cache(async () => { - return mockProjects; + const projects = await serverFetchJson( + `${BASE_API_URL}/projects`, + { + next: { tags: ["projects"] }, + }, + ); + + // TODO: Replace this with a project + return projects.map( + ({ id, code, name, projectCategory, teamLead, customer }) => ({ + id, + code, + name, + category: projectCategory.name, + team: teamLead.team.code, + client: customer.name, + }), + ); }); export const fetchProjectCategories = cache(async () => { - return mockProjectCategories; + return serverFetchJson( + `${BASE_API_URL}/projects/categories`, + { + next: { tags: ["projectCategories"] }, + }, + ); }); -const mockProjectCategories: ProjectCategory[] = [ - { id: 1, label: "Confirmed Project" }, - { id: 2, label: "Project to be bidded" }, -]; - const mockProjects: ProjectResult[] = [ { id: 1, diff --git a/src/app/api/staff/index.ts b/src/app/api/staff/index.ts new file mode 100644 index 0000000..617169b --- /dev/null +++ b/src/app/api/staff/index.ts @@ -0,0 +1,24 @@ +import { serverFetchJson } from "@/app/utils/fetchUtil"; +import { BASE_API_URL } from "@/config/api"; +import { cache } from "react"; +import "server-only"; + +export interface Staff { + id: number; + name: string; + staffId: string; + team: { + name: string; + code: string; + }; +} + +export const preloadStaff = () => { + fetchTeamLeads(); +}; + +export const fetchTeamLeads = cache(async () => { + return serverFetchJson(`${BASE_API_URL}/staffs/teamLeads`, { + next: { tags: ["teamLeads"] }, + }); +}); diff --git a/src/app/utils/fetchUtil.ts b/src/app/utils/fetchUtil.ts index 718dd30..2bafa9e 100644 --- a/src/app/utils/fetchUtil.ts +++ b/src/app/utils/fetchUtil.ts @@ -32,6 +32,7 @@ export async function serverFetchJson(...args: FetchParams) { case 401: signOutUser(); default: + console.error(await response.text()); throw Error("Something went wrong fetching data in server."); } } diff --git a/src/components/CreateProject/CreateProject.tsx b/src/components/CreateProject/CreateProject.tsx index e5198f9..e6c8e21 100644 --- a/src/components/CreateProject/CreateProject.tsx +++ b/src/components/CreateProject/CreateProject.tsx @@ -21,14 +21,17 @@ import { SubmitHandler, useForm, } from "react-hook-form"; -import { CreateProjectInputs } from "@/app/api/projects/actions"; +import { CreateProjectInputs, saveProject } from "@/app/api/projects/actions"; import { Error } from "@mui/icons-material"; import { ProjectCategory } from "@/app/api/projects"; +import { Staff } from "@/app/api/staff"; +import { Typography } from "@mui/material"; export interface Props { allTasks: Task[]; projectCategories: ProjectCategory[]; taskTemplates: TaskTemplate[]; + teamLeads: Staff[]; } const hasErrorsInTab = ( @@ -47,7 +50,9 @@ const CreateProject: React.FC = ({ allTasks, projectCategories, taskTemplates, + teamLeads, }) => { + const [serverError, setServerError] = useState(""); const [tabIndex, setTabIndex] = useState(0); const { t } = useTranslation(); const router = useRouter(); @@ -63,9 +68,19 @@ const CreateProject: React.FC = ({ [], ); - const onSubmit = useCallback>((data) => { - console.log(data); - }, []); + const onSubmit = useCallback>( + async (data) => { + try { + console.log(data); + setServerError(""); + await saveProject(data); + router.replace("/projects"); + } catch (e) { + setServerError(t("An error has occurred. Please try again later.")); + } + }, + [router, t], + ); const onSubmitError = useCallback>( (errors) => { @@ -82,6 +97,8 @@ const CreateProject: React.FC = ({ tasks: {}, allocatedStaffIds: [], milestones: {}, + // TODO: Remove this + clientSubsidiary: "Test subsidiary", }, }); @@ -111,6 +128,7 @@ const CreateProject: React.FC = ({ { } @@ -123,6 +141,11 @@ const CreateProject: React.FC = ({ } {} {} + {serverError && ( + + {serverError} + + )}