Skip to content

Commit

Permalink
Merge branch 'main' into quoc
Browse files Browse the repository at this point in the history
  • Loading branch information
bvquoc committed Dec 24, 2023
2 parents 7f95e28 + 7b5a688 commit f2b2309
Show file tree
Hide file tree
Showing 38 changed files with 1,928 additions and 456 deletions.
3 changes: 3 additions & 0 deletions book-store-management/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,6 @@ input[type="range"]::-webkit-slider-thumb {
.error___message {
@apply text-sm text-red-700;
}
@page {
margin: 32px 0 !important;
}
70 changes: 70 additions & 0 deletions book-store-management/app/invoice/[invoiceId]/detail-layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"use client";
import React from "react";
import { InvoiceDetailTable } from "@/components/invoice/invoice-detail-table";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { toVND } from "@/lib/utils";
import Image from "next/image";
import { useRef } from "react";
import ReactToPrint from "react-to-print";
import { InvoiceDetailProps } from "./page";
import { FaPrint } from "react-icons/fa";
const DetailLayout = (responseData: any) => {
const componentRef = useRef(null);
const details = responseData.details as InvoiceDetailProps[];
return (
<Card>
<CardContent className="flex flex-col p-0 gap-4 relative">
<ReactToPrint
trigger={() => {
return (
<Button
variant={"outline"}
className="absolute top-6 right-6 flex gap-2"
>
<FaPrint className="w-5 h-5 text-primary" />
In
</Button>
);
}}
content={() => componentRef.current}
/>
<div ref={componentRef} className="p-6 ">
<div className="flex justify-center gap-2 mb-6">
<Image
className="object-contain w-auto h-auto"
src="/android-chrome-192x192.png"
priority
alt="logo"
width={50}
height={50}
></Image>
<h1 className=" py-6 text-3xl uppercase font-medium">Nhà sách</h1>
</div>

<div className="flex flex-row justify-between p-4 mb-6 border rounded-md">
<div className="flex gap-2">
<span className="font-light">Mã hóa đơn:</span>
<span className="font-semibold">{responseData.id}</span>
</div>
<div className="flex flex-col items-end gap-2 text-sm">
<span className="font-semibold">
{new Date(responseData.createdAt).toLocaleDateString("vi-VN")}
</span>
<span>Nhân viên: {responseData.createdBy.name}</span>
</div>
</div>
<div className="flex flex-col gap-4">
<InvoiceDetailTable {...details} />
<div className="flex justify-end space-x-2 py-4 font-semibold">
<span>Tổng tiền: </span>
<span>{toVND(responseData.totalPrice)}</span>
</div>
</div>
</div>
</CardContent>
</Card>
);
};

export default DetailLayout;
67 changes: 14 additions & 53 deletions book-store-management/app/invoice/[invoiceId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { InvoiceDetailTable } from "@/components/invoice/invoice-detail-table";
import RecordNotFound from "@/components/record-notfound";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import getInvoiceDetail from "@/lib/invoice/getInvoiceDetail";
import { toVND } from "@/lib/utils";
import Image from "next/image";
import { useRef } from "react";
import ReactToPrint from "react-to-print";
import DetailLayout from "./detail-layout";

export type InvoiceDetailProps = {
book: { id: string; name: string };
qty: number;
unitPrice: number;
};
const InvoiceDetails = async ({
params,
}: {
Expand All @@ -12,65 +23,15 @@ const InvoiceDetails = async ({
idInvoice: params.invoiceId,
});
const responseData = await response;
console.log(responseData);
if (responseData.hasOwnProperty("errorKey")) {
return <RecordNotFound />;
} else {
console.log(responseData.details);
const details = responseData.details as {
book: { id: string; name: string };
qty: number;
unitPrice: number;
}[];
// console.log(responseData.details);

return (
<div className="col items-center">
<div className="col xl:w-4/5 w-full xl:px-0 md:px-8 px-0">
<h1 className="lg:text-3xl text-2xl">
Mã hóa đơn: {params.invoiceId}
</h1>
<Card>
<CardContent className="p-6 px-2 flex flex-col gap-4">
<h1 className="text-base px-4">Thông tin chung</h1>

<div className="flex flex-row justify-between pb-2 px-4 border-b">
<h2>Ngày tạo: </h2>
<span>
{new Date(responseData.createdAt).toLocaleDateString("vi-VN")}
</span>
</div>
<div className="flex flex-row justify-between pb-2 px-4 border-b">
<h2>Người tạo: </h2>
<span>{responseData.createdBy.name}</span>
</div>
<div className="flex flex-row justify-between px-4 ">
<h2>Tổng hóa đơn: </h2>
<span>{toVND(responseData.totalPrice)}</span>
</div>
</CardContent>
</Card>
<Card>
<CardContent className="p-6 px-2 flex flex-col gap-4">
<h1 className="text-base px-4">Thông tin thanh toán</h1>
{details.map((item, index) => {
return (
<div
key={item.book.id}
className={`flex flex-row justify-between pb-2 px-4 ${
index < details.length - 1 ? "border-b" : ""
}`}
>
<span>{item.book.name}</span>
<div>
<span className="text-center"> {item.qty} x </span>
<span className="text-right">
{toVND(item.unitPrice)}
</span>
</div>
</div>
);
})}
</CardContent>
</Card>
<DetailLayout {...responseData} />
</div>
</div>
);
Expand Down
51 changes: 25 additions & 26 deletions book-store-management/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,34 @@ import { Toaster } from "@/components/ui/toaster";
const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
title: "Nhà sách",
description: "Book store management app",
icons: {
icon: ["/favicon.ico?v=4"],
apple: ["/apple-touch-icon.png?v=4"],
shortcut: ["apple-touch-icon.png"],
},
manifest: "/site.webmanifest",
title: "Nhà sách",
description: "Book store management app",
icons: {
icon: ["/favicon.ico?v=4"],
apple: ["/apple-touch-icon.png?v=4"],
shortcut: ["apple-touch-icon.png"],
},
manifest: "/site.webmanifest",
};

export default function RootLayout({
children,
children,
}: {
children: React.ReactNode;
children: React.ReactNode;
}) {
return (
<html lang="en" className="h-full">
<body className={`${inter.className} flex overflow-y-hidden h-full`}>
<Sidebar />
<main className="flex flex-1">
<div className="flex w-full flex-col overflow-y-hidden">
<Header />
<HeaderMobile />
<div className="md:p-10 p-4 overflow-auto">{children}</div>
<Toaster />
</div>
</main>
</body>
</html>
);
return (
<html lang="en" className="h-full">
<body className={`${inter.className} flex overflow-y-hidden h-full`}>
<Sidebar />
<main className="flex flex-1">
<div className="flex w-full flex-col overflow-y-hidden">
<Header />
<HeaderMobile />
<div className="md:p-10 p-4 overflow-auto">{children}</div>
<Toaster />
</div>
</main>
</body>
</html>
);
}
export const revalidate = 0;
4 changes: 3 additions & 1 deletion book-store-management/app/product/books/add/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import BookTitleSelect from "@/components/book-manage/book-title-select";
import PublisherList from "@/components/book-manage/publisher-list";
import createBook from "@/lib/book/createBook";
import { useSWRConfig } from "swr";
import { useRouter } from "next/navigation";

const FormSchema = z.object({
bookTitleId: z.string().min(1, "Vui lòng chọn một đầu sách"),
Expand Down Expand Up @@ -62,7 +63,7 @@ const InsertNewBook = () => {
} = form;

const [publisherId, setPublisherId] = useState("");

const router = useRouter();
const handleTitleSet = (idTitle: string) => {
setValue("bookTitleId", idTitle);
trigger("bookTitleId");
Expand Down Expand Up @@ -98,6 +99,7 @@ const InsertNewBook = () => {
description: "Thêm mới sách thành công",
});
mutate(`${endPoint}/v1/books/all`);
router.refresh();
}
};
return (
Expand Down
11 changes: 11 additions & 0 deletions book-store-management/app/product/title/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import TableLayout from "./table-layout";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "Đầu sách",
};
const BookTitleScreen = () => {
return <TableLayout />;
};

export default BookTitleScreen;
80 changes: 80 additions & 0 deletions book-store-management/app/product/title/table-layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"use client";

import CreateTitleDialog from "@/components/book-manage/create-title-dialog";
import { TitleTable } from "@/components/book-manage/title-table";
import { Button } from "@/components/ui/button";
import { endPoint } from "@/constants";
import { useRouter, useSearchParams } from "next/navigation";
import { useSWRConfig } from "swr";

export const getFilterString = () => {
const searchParams = useSearchParams();
const minPrice = searchParams.get("minPrice") ?? undefined;
const maxPrice = searchParams.get("maxPrice") ?? undefined;
const createdAtFrom = searchParams.get("createdAtFrom") ?? undefined;
const createdAtTo = searchParams.get("createdAtTo") ?? undefined;

const search = searchParams.get("search") ?? undefined;

let filters = [{ type: "", value: "" }];
filters.pop();
if (maxPrice) {
filters = filters.concat({ type: "maxPrice", value: maxPrice });
}
if (minPrice) {
filters = filters.concat({ type: "minPrice", value: minPrice });
}
if (search) {
filters = filters.concat({ type: "search", value: search });
}
if (createdAtFrom) {
filters = filters.concat({ type: "createdAtFrom", value: createdAtFrom });
}
if (createdAtTo) {
filters = filters.concat({ type: "createdAtTo", value: createdAtTo });
}
let stringToFilter = "";
filters.forEach((item) => {
stringToFilter = stringToFilter.concat(`&${item.type}=${item.value}`);
});
return { stringToFilter: stringToFilter, filters: filters };
};

const TableLayout = () => {
const router = useRouter();
const searchParams = useSearchParams();
const { mutate } = useSWRConfig();

const { filters, stringToFilter } = getFilterString();
const page = searchParams.get("page") ?? "1";

const handleTitleAdded = async (titleId: string) => {
mutate(
`${endPoint}/v1/booktitles?page=${page ?? 1}&limit=10${
stringToFilter ?? ""
}`
);
// const newTitleList = await mutate();
// setTitle(
// newTitleList?.data.find((item: BookTitle) => item.id === titleId)
// );
// handleTitleSet(titleId);
router.refresh();
};
return (
<div className="col">
<div className="flex flex-row justify-between items-center">
<h1>Danh sách đầu sách</h1>
<CreateTitleDialog handleTitleAdded={handleTitleAdded}>
<Button>Thêm đầu sách</Button>
</CreateTitleDialog>
</div>

<div className="my-4 p-3 sha bg-white shadow-[0_1px_3px_0_rgba(0,0,0,0.2)]">
<TitleTable />
</div>
</div>
);
};

export default TableLayout;
2 changes: 2 additions & 0 deletions book-store-management/app/sale/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ const SaleScreen = () => {
watch={watch}
control={control}
remove={remove}
reset={reset}
/>
</div>
<div className="fixed bottom-0 left-0 right-0">
Expand Down Expand Up @@ -155,6 +156,7 @@ const SaleScreen = () => {
watch={watch}
control={control}
remove={remove}
reset={reset}
isSheet
/>
</SheetContent>
Expand Down
Loading

0 comments on commit f2b2309

Please sign in to comment.