Преглед изворни кода

1. Add Create Company Page

2. Add Invoice search page
tags/Baseline_30082024_FRONTEND_UAT
MSI\2Fi пре 1 година
родитељ
комит
2ec7e15042
8 измењених фајлова са 311 додато и 8 уклоњено
  1. +25
    -0
      src/app/(main)/invoice/new/page.tsx
  2. +30
    -1
      src/app/(main)/invoice/page.tsx
  3. +9
    -7
      src/app/(main)/settings/company/create/page.tsx
  4. +25
    -0
      src/app/api/companys/actions.ts
  5. +110
    -0
      src/components/CreateCompany/CompanyDetails.tsx
  6. +101
    -0
      src/components/CreateCompany/CreateCompany.tsx
  7. +10
    -0
      src/components/CreateCompany/CreateCompanyWrapper.tsx
  8. +1
    -0
      src/components/CreateCompany/index.ts

+ 25
- 0
src/app/(main)/invoice/new/page.tsx Прегледај датотеку

@@ -0,0 +1,25 @@
import { Metadata } from "next";
import { getServerI18n } from "@/i18n";
import Add from "@mui/icons-material/Add";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import Link from "next/link";

export const metadata: Metadata = {
title: "Create Invoice",
};

const Invoice: React.FC = async () => {
const { t } = await getServerI18n("Create Invoice");

return (
<>
<Typography variant="h4" marginInlineEnd={2}>
{t("Create Invoice")}
</Typography>
</>
)
};

export default Invoice;

+ 30
- 1
src/app/(main)/invoice/page.tsx Прегледај датотеку

@@ -1,11 +1,40 @@
import { Metadata } from "next";
import { getServerI18n } from "@/i18n";
import Add from "@mui/icons-material/Add";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import Link from "next/link";

export const metadata: Metadata = {
title: "Invoice",
};

const Invoice: React.FC = async () => {
return "Invoice";
const { t } = await getServerI18n("Invoice");

return (
<>
<Stack
direction="row"
justifyContent="space-between"
flexWrap="wrap"
rowGap={2}
>
<Typography variant="h4" marginInlineEnd={2}>
{t("Invoice")}
</Typography>
<Button
variant="contained"
startIcon={<Add />}
LinkComponent={Link}
href="/invoice/new"
>
{t("Create Invoice")}
</Button>
</Stack>
</>
)
};

export default Invoice;

+ 9
- 7
src/app/(main)/settings/company/create/page.tsx Прегледај датотеку

@@ -1,20 +1,22 @@
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 CreateCompany from "@/components/CreateCompany";
import { I18nProvider, getServerI18n } from "@/i18n";
import Typography from "@mui/material/Typography";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "Create Project",
title: "Create Comapny",
};
const Companys: React.FC = async () => {
const { t } = await getServerI18n("projects");
const { t } = await getServerI18n("companys");
return(
<>AAAA</>
<>
<Typography variant="h4">{t("Create Company")}</Typography>
<I18nProvider namespaces={["companys"]}>
<CreateCompany />
</I18nProvider>
</>
)

}


+ 25
- 0
src/app/api/companys/actions.ts Прегледај датотеку

@@ -1,4 +1,5 @@
"use server";

import { serverFetchJson } from "@/app/utils/fetchUtil";
import { BASE_API_URL } from "@/config/api";
import { cache } from "react";
@@ -12,6 +13,30 @@ export interface combo {
records: comboProp[];
}

export interface CreateCompanyInputs {
companyCode: String;
companyName: String;
brNo: String;
contactName: String;
phone: String;
otHourTo: String;
otHourFrom: String;
normalHourTo: String;
normalHourFrom: String;
currency: String;
address: String;
distract: String;
email: String;
}

export const saveCompany = async (data: CreateCompanyInputs) => {
return serverFetchJson(`${BASE_API_URL}/companys/new`, {
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
});
};

export const fetchCompanyCombo = cache(async () => {
return serverFetchJson<combo>(`${BASE_API_URL}/companys/combo`, {
next: { tags: ["company"] },


+ 110
- 0
src/components/CreateCompany/CompanyDetails.tsx Прегледај датотеку

@@ -0,0 +1,110 @@
"use client";

import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import FormControl from "@mui/material/FormControl";
import Grid from "@mui/material/Grid";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import Select from "@mui/material/Select";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import { useTranslation } from "react-i18next";
import CardActions from "@mui/material/CardActions";
import RestartAlt from "@mui/icons-material/RestartAlt";
import Button from "@mui/material/Button";
import { Controller, useFormContext } from "react-hook-form";
import { CreateCompanyInputs } from "@/app/api/companys/actions";

const CompanyDetails: React.FC = ({
}) => {
const { t } = useTranslation();
const {
register,
formState: { errors },
control,
} = useFormContext<CreateCompanyInputs>();

return (
<Card>
<CardContent component={Stack} spacing={4}>
<Box>
<Typography variant="overline" display="block" marginBlockEnd={1}>
{t("Company Details")}
</Typography>
<Grid container spacing={2} columns={{ xs: 6, sm: 12 }}>
<Grid item xs={6}>
<TextField
label={t("Company Code")}
fullWidth
{...register("companyCode", {
required: "Company code required!",
})}
error={Boolean(errors.companyCode)}
/>
</Grid>
<Grid item xs={6}>
<TextField
label={t("Company Name")}
fullWidth
{...register("companyName", {
required: "Company name required!",
})}
error={Boolean(errors.companyName)}
/>
</Grid>
<Grid item xs={6}>
<TextField
label={t("Company brNo")}
fullWidth
{...register("brNo", {
required: "Please enter a brNo",
})}
error={Boolean(errors.brNo)}
/>
</Grid>
<Grid item xs={6}>
<TextField
label={t("Company contact name")}
fullWidth
{...register("contactName", {
required: "Please enter a contact name",
})}
error={Boolean(errors.contactName)}
/>
</Grid>
<Grid item xs={6}>
<TextField
label={t("Company contact number")}
fullWidth
{...register("phone", {
required: "Please enter a contact number",
})}
error={Boolean(errors.phone)}
/>
</Grid>
<Grid item xs={6}>
<TextField
label={t("Company contact email")}
fullWidth
{...register("email", {
required: "Please enter a contact email",
})}
error={Boolean(errors.email)}
/>
</Grid>
</Grid>
</Box>
{/* <CardActions sx={{ justifyContent: "flex-end" }}>
<Button variant="text" startIcon={<RestartAlt />}>
{t("Reset")}
</Button>
</CardActions> */}
</CardContent>
</Card>
);
};

export default CompanyDetails;

+ 101
- 0
src/components/CreateCompany/CreateCompany.tsx Прегледај датотеку

@@ -0,0 +1,101 @@
"use client";

import Check from "@mui/icons-material/Check";
import Close from "@mui/icons-material/Close";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import { CreateCompanyInputs, saveCompany } from "@/app/api/companys/actions";
import { useRouter } from "next/navigation";
import React, { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import {
FieldErrors,
FormProvider,
SubmitErrorHandler,
SubmitHandler,
useForm,
} from "react-hook-form";
import CompanyDetails from "./CompanyDetails";

const CreateCompany: React.FC = ({

}) => {
const [serverError, setServerError] = useState("");
const { t } = useTranslation();
const router = useRouter();

const handleCancel = () => {
router.back();
};

const onSubmit = useCallback<SubmitHandler<CreateCompanyInputs>>(
async (data) => {
try {
console.log(data);
setServerError("");
// console.log(JSON.stringify(data));
await saveCompany(data)
router.replace("/settings/companys");
} catch (e) {
setServerError(t("An error has occurred. Please try again later."));
}
},
[router, t],
);

const onSubmitError = useCallback<SubmitErrorHandler<CreateCompanyInputs>>(
(errors) => {
console.log(errors)
},
[],
);

const formProps = useForm<CreateCompanyInputs>({
defaultValues: {
companyCode: "",
companyName: "",
brNo: "",
contactName: "",
phone: "",
otHourTo: "",
otHourFrom: "",
normalHourTo: "",
normalHourFrom: "",
currency: "",
address: "",
distract: "",
email: "",
},
});
const errors = formProps.formState.errors;

return(
<FormProvider {...formProps}>
<Stack
spacing={2}
component="form"
onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
>
{
<CompanyDetails />
}

<Stack direction="row" justifyContent="flex-end" gap={1}>
<Button
variant="outlined"
startIcon={<Close />}
onClick={handleCancel}
>
{t("Cancel")}
</Button>
<Button variant="contained" startIcon={<Check />} type="submit">
{t("Confirm")}
</Button>
</Stack>
</Stack>
</FormProvider>
)
}

export default CreateCompany;

+ 10
- 0
src/components/CreateCompany/CreateCompanyWrapper.tsx Прегледај датотеку

@@ -0,0 +1,10 @@
import CreateCompany from "./CreateCompany";

const CreateCompanyWrapper: React.FC = async () => {
return (
<CreateCompany
/>
)
}

export default CreateCompanyWrapper;

+ 1
- 0
src/components/CreateCompany/index.ts Прегледај датотеку

@@ -0,0 +1 @@
export { default } from "./CreateCompanyWrapper"

Loading…
Откажи
Сачувај