Skip to content

Commit

Permalink
Merge pull request #11 from Cubeseed/feat/create-invoice-mod
Browse files Browse the repository at this point in the history
Feat/create invoice mod
  • Loading branch information
abu-hasib authored Jul 31, 2023
2 parents bbadc2b + c4b7443 commit 50d7e41
Show file tree
Hide file tree
Showing 29 changed files with 5,071 additions and 7 deletions.
1 change: 1 addition & 0 deletions cubeseed_login/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# misc
.DS_Store
*.pem
.vscode

# debug
npm-debug.log*
Expand Down
10 changes: 10 additions & 0 deletions cubeseed_login/app/(processor)/dashboard/invoice/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import ViewInvoice from "@cs/components/view-invoice";
import CreateInvoice from "../../../../components/create-invoice";

export default async function InvoicePage() {
return (
<div className="p-8">
<ViewInvoice />
</div>
)
}
27 changes: 27 additions & 0 deletions cubeseed_login/app/(processor)/dashboard/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Navbar from "@/component/navbar/Navbar";
import DashboardNavbar from "@/component/dashboard/DashboardNavbar/DashboardNavbar";

export const metadata = {
title: "Next.js",
description: "Generated by Next.js",
};

export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="flex min-h-screen flex-col">
<header className="sticky inset-0 ">
<Navbar />
</header>
<div>
<aside className="w-[250px] h-screen fixed inset-0 bg-white shadow-2xl">
<DashboardNavbar />
</aside>
<main className="ml-[250px]">{children}</main>
</div>
</div>
);
}
11 changes: 11 additions & 0 deletions cubeseed_login/app/(processor)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import CreateInvoice from "@cs/components/create-invoice";
import CreateSucess from "@cs/components/create-success";
import { useState } from "react";

export default async function DashboardPage() {
return (
<div>
<CreateInvoice />
</div>
);
}
25 changes: 25 additions & 0 deletions cubeseed_login/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// import "@/styles/global.css"
import "@/styles/global.css"
import { Inter as FontSans } from "next/font/google"

export const metadata = {
title: 'Next.js',
description: 'Generated by Next.js',
}

const fontSans = FontSans({
variable: '--font-sans',
subsets: ['latin']
})

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={`font-sans ${fontSans.variable}`}>{children}</body>
</html>
)
}
3 changes: 3 additions & 0 deletions cubeseed_login/assets/svg/cal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions cubeseed_login/assets/svg/download.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions cubeseed_login/assets/svg/face.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions cubeseed_login/assets/svg/pending.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
241 changes: 241 additions & 0 deletions cubeseed_login/components/create-invoice.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
"use client";

import Image from "next/image";
import { useState } from "react";
import billto from "@cs/public/bill-to.png";
import payto from "@cs/public/pay-to.png";
import Input from "./pieces/input";
import Textarea from "./pieces/textarea";
import Table from "./pieces/table";
import CreateSucess from "./create-success";
import { BillType, OrderType, SummaryType } from "@cs/types";
import { DashboardHeading } from "./header";

export default function CreateInvoice() {
const [shouldOpen, setOpen] = useState(false)
const [isSuccess, setSuccess] = useState(false)

const billerData = [
{ name: "Name", value: "Farmer&apos;s name" },
{ name: "Company", value: "Farm name" },
{
name: "Contact",
value: `+230 200 6005 email@site.com`,
},
{
name: "Address",
value: "Building, Street Address City, State/Province, Country",
},
];

const renderBiller = (item: BillType) => (
<tr>
<td className="px-3">{item.name}</td>
<td className="px-3">{item.value}</td>
</tr>
);

const orderHeaders = [
"Service",
"Quantity",
"kg/ml",
"Unit Price",
"Total Price",
];

const orderData = [
{
service: "Strawberry Jam",
quantity: "50",
unit: "kg/ml",
price: "#5.00",
total: "₦250",
},
{
service: "Strawberry Jam",
quantity: "50",
unit: "kg/ml",
price: "#5.00",
total: "₦250",
},
];

const renderOrder = (item: OrderType) => (
<>
<tr className="bg-[#F9FFFF]">
<td className="p-4">{item.service}</td>
<td>{item.quantity}</td>
<td>{item.unit}</td>
<td>{item.price}</td>
<td>{item.total}</td>
</tr>
<tr>
<td colSpan={4} className="p-4">
<span className="block">Details</span>
<span>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Magni,
natus!
</span>
</td>
</tr>
</>
);

const summmaryData = [
{ name: "Total Quantity:", value: "150kg" },
{ name: "Subtotal:", value: "₦ 750.00" },
{ name: "Total Tax:", value: "₦ 00.00" },
];

const renderSummary = (item: SummaryType) => (
<tr>
<td className="text-right">{item.name}:</td>
<td className="text-right p-1">{item.value}</td>
</tr>
);

return (
<div className="flex pt-8 px-4 justify-end relative">
<div>
<button
className="text-[#886634] font-light rounded-[100px] py-3 px-6 h-[44px] bg-transparent flex items-center border border-yellow-400"
onClick={() => setOpen(true)}
>
Create +
</button>
</div>
{shouldOpen && (
<div className="grid items-center h-screen w-screen fixed inset-0 backdrop-brightness-50">
<div className="w-[60%] bg-white mx-auto self-start mt-8 overflow-auto max-h-[90%] relative rounded-bl-[35px] shadow-lg">
<div className="relative p-8 pb-16 text-[#002629]">
<DashboardHeading
heading="Invoice"
text="Fill out the missing information and an invoice will be created
and sent to [farmer’s name]."
subheading="Order ID &gt; Invoice ID "
/>
<span
className="grid items-center absolute right-[3%] top-[1%] cursor-pointer z-10 rounded-full"
onClick={() => setOpen(false)}
>
X
</span>
<form action="">
<div>
<h2 className="mt-8">Add Information</h2>
<div className="flex gap-4 mt-8">
<Input label="Invoice Date" type="date" />
<Input label="Payment Due Date" type="date" />
</div>
<div className="mt-4">
<Textarea
className="w-full border rounded-[4px] border-gray-300 text-gray-900"
name=""
id=""
rows={4}
label="Notes(optional)"
/>
<p className="font-normal text-sm text-right text-[#6A7370]">
200 characters left
</p>
</div>
<section>
<h4>Bill to</h4>
<div className="flex gap-4 p-6 bg-[#F0F6F6] rounded-[20px] mt-4">
<div>
<Image
src={billto}
width={88}
height={88}
alt="@/public/bill-to.png"
className="rounded-full "
/>
</div>
<Table items={billerData} render={renderBiller} />
</div>
</section>
<section className="mt-8">
<h4>Pay to</h4>
<div className="flex gap-4 p-6 bg-[#F0F6F6] rounded-[20px] mt-4">
<div>
<Image
src={payto}
width={88}
height={88}
alt="pay to"
className="rounded-full "
/>
</div>
<Table items={billerData} render={renderBiller} />
</div>
</section>
<section className="mt-8">
<h4>Order</h4>
<div className="mt-4">
<Table
headers={orderHeaders}
items={orderData}
render={renderOrder}
className="w-full font-normal text-sm border border-[#03656B] rounded-[4px] text-left"
thStyle="border-b border-[#03656B]"
/>
</div>
</section>

<section className="flex justify-end mt-8">
<div className="border border-[#03656B] bg-[#F9FFFF] rounded-[4px] w-[70%] py-4 px-8">
<Table
items={summmaryData}
render={renderSummary}
className="w-full font-normal text-sm text-[#03656B]"
extra={
<tr className="text-black border-t border-[#03656B]">
<td className="text-right">Total Estimate:</td>
<td className="text-right p-1">₦ 0,000.00</td>
</tr>
}
/>
</div>
</section>

<section className="mt-8">
<h4 className="font-normal text-base">Sign and Date</h4>
<div className="flex mt-6 gap-4">
<input type="checkbox" name="" id="" />
<p className="font-normal text-sm">
Confirm that you have reviewed the information above.
</p>
</div>
<div className="flex gap-2 mt-6">
<Input label="Your Signature" type="text" />
<Input label="Today's Date" type="date" />
</div>
</section>
</div>
</form>
</div>
<footer className="sticky z-10 bottom-0 left-0 bg-white shadow-[0px_-7px_10px_0px_#03656B24] p-4 text-base">
<div className="flex justify-between w-full">
<button className="text-white font-light bg-[#03656B] rounded-[100px] py-3 px-6 h-[44px] flex items-center">
Close
</button>
<div className="flex gap-4">
<button className="text-[#886634] font-light rounded-[100px] py-3 px-6 h-[44px] bg-transparent flex items-center border border-yellow-400">
Save as Draft
</button>
<button
onClick={() => setSuccess(true)}
className="text-white font-light bg-[#03656B] rounded-[100px] py-3 px-6 h-[44px] flex items-center"
>
Send Invoice
</button>
</div>
</div>
</footer>
</div>
</div>
)}
{isSuccess && <CreateSucess isSuccess={isSuccess} setSuccess={setSuccess} />}
</div>
);
}
36 changes: 36 additions & 0 deletions cubeseed_login/components/create-success.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Image from "next/image";
import check from "@cs/public/check.svg";
import ellipse from "@cs/public/ellipse.png";
import Link from "next/link";

export interface CreateSuccessProps {
isSuccess: boolean;
setSuccess: React.Dispatch<React.SetStateAction<boolean>>;
}

export default function CreateSucess({ isSuccess, setSuccess }: CreateSuccessProps) {
if(!isSuccess) return null;
return (
<div className="grid items-center h-screen w-screen fixed inset-0 backdrop-brightness-[30%]">
<div className="grid place-items-center w-[60%] py-8 px-8 bg-white text-primary-100 mx-auto max-h-[90%] shadow-lg relative rounded-[25px]">
<span
className="grid items-center absolute right-[3%] top-[1%] cursor-pointer z-10"
onClick={() => setSuccess(false)}
>
X
</span>
<div>
<Image src={check} alt={check} />
</div>
<p className="text-[22px] font-medium">Your invoice has been sent successfully!</p>
<p>Your invoice can now be downloaded.</p>
<div className="w-full flex justify-between font-medium mt-20">
<button onClick={() => setSuccess(false)} className="text-accent rounded-[100px] py-3 px-6 h-[44px] bg-transparent flex items-center border-2 border-secondary">
Close
</button>
<Link className="bg-secondary text-black rounded-[100px] py-3 px-6 h-[44px] flex items-center" href="dashboard/invoice">View Invoice</Link>
</div>
</div>
</div>
);
}
Loading

0 comments on commit 50d7e41

Please sign in to comment.