Skip to content

Commit

Permalink
Merge pull request #332 from alialaba/feat/HNG-69-invoice-email-temp
Browse files Browse the repository at this point in the history
feat:Email Template > Invoice Email Template
  • Loading branch information
mrcoded authored Jul 22, 2024
2 parents 44e7f3f + 13200ab commit 7a56cfd
Show file tree
Hide file tree
Showing 13 changed files with 390 additions and 15 deletions.
42 changes: 42 additions & 0 deletions app/components/InvoiceEmail/DetailTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Column, Heading, Row, Section, Text } from "@react-email/components";

interface Detail {
id: number;
label: string;
value: string;
}

interface DetailTableProperties {
title: string;
text: string;
details: Detail[];
}

const DetailTable = ({ title, text, details }: DetailTableProperties) => {
return (
<Section className="my-6" style={{ borderTop: "1px solid #CBD5E1" }}>
<Heading className="my-4 font-semibold">{title}</Heading>
{text && <Text className="-mt-4">{text}</Text>}

<div
className="rounded-lg p-6 py-2"
style={{ backgroundColor: "#F6F8FB" }}
>
{details.map((detail) => (
<Row className="border-b last:border-none" key={detail.id}>
<div className="align-center flex justify-between">
<Column className="py-2 text-sm text-[#434343]">
{detail.label}
</Column>
<Column className="py-2 text-sm font-semibold text-[#0A0A0A]">
{detail.value}
</Column>
</div>
</Row>
))}
</div>
</Section>
);
};

export default DetailTable;
59 changes: 59 additions & 0 deletions app/components/InvoiceEmail/EmailFooter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Img, Link } from "@react-email/components";

export default function EmailFooter() {
return (
<div className="m-auto w-[4/5] justify-center bg-[#F3EFEF] px-[48px] py-[32px] leading-[normal] tracking-[normal]">
<div className="mx-auto flex flex-col items-start justify-start gap-7 text-left text-sm">
<div className="flex w-full items-center justify-center gap-[33px]">
<Link>
<Img src="/public/icons/x.svg" />
</Link>
<Link>
<Img src="/public/icons/instagram.svg" />
</Link>
<Link>
<Img src="/public/icons/tiktok.svg" />
</Link>
<Link>
<Img src="/public/icons/reddit.svg" />
</Link>
<Link>
<Img src="/public/icons/linkedin.svg" />
</Link>
</div>
<p className="text-[14px] text-[#5B5B5D]">
{`Thank you for choosing Boilerplate.com. Need help? `}
<Link
className="font-semibold text-black underline hover:no-underline"
href="#"
>
Contact our customer support
</Link>
</p>
<div className="h-0 w-full border-t border-dashed border-[#5B5B5D]"></div>
<p className="flex flex-col gap-3 text-[14px] text-[#5B5B5D]">
<span className="block">
You are receiving this email because you signed up at
Boilerplate.com. Want to change how you receive these emails?
</span>
<span>
You can
<Link
className="pl-1 font-semibold text-black underline hover:no-underline"
href="#"
>
Update your preference
</Link>
or
<Link
className="pl-1 font-semibold text-black underline hover:no-underline"
href="#"
>
Unsuscribe from this list.
</Link>
</span>
</p>
</div>
</div>
);
}
45 changes: 45 additions & 0 deletions app/components/InvoiceEmail/OrderSummaryTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Column, Heading, Row, Section } from "@react-email/components";

interface OrderDetail {
id: number;
label: string;
value: string;
amt: string;
}

interface OrderSummaryTableProperties {
title: string;
details: OrderDetail[];
}

const OrderSummaryTable = ({ title, details }: OrderSummaryTableProperties) => {
return (
<Section className="my-6" style={{ borderTop: "1px solid #CBD5E1" }}>
<div>
<Heading className="my-4 font-semibold">{title}</Heading>
</div>
<div
className="rounded-lg px-6 py-2"
style={{ backgroundColor: "#F6F8FB" }}
>
{details.map((detail) => (
<Row className="border-b last:border-none" key={detail.id}>
<div className="align-center flex justify-between">
<Column className="py-2 text-sm text-[#434343]">
{detail.label}
</Column>
<Column className="py-2 text-center text-sm">
{detail.value}
</Column>
<Column className="py-2 text-sm font-semibold text-[#0A0A0A]">
{detail.amt}
</Column>
</div>
</Row>
))}
</div>
</Section>
);
};

export default OrderSummaryTable;
167 changes: 167 additions & 0 deletions app/email/templates/invoice-email-temp/InvoiceEmail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import {
Body,
Button,
Container,
Head,
Heading,
Html,
Img,
Link,
Section,
Tailwind,
Text,
} from "@react-email/components";

import DetailTable from "~/components/InvoiceEmail/DetailTable";
import EmailFooter from "~/components/InvoiceEmail/EmailFooter";
import OrderSummaryTable from "~/components/InvoiceEmail/OrderSummaryTable";
import { invoiceDetails, orderSummary, paymentDetails } from "./data";

interface infoProperties {
phone: string;
email: string;
}

const InvoiceEmail = ({
phone = "-456-7890",
email = "[email protected]",
}: infoProperties) => {
return (
<>
<Html>
<Head>
<style>
{`
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap');
@media (min-width: 640px) {
.container-width {
max-width: 420px;
}
.show{
visibility: hidden;
}
}
@media (min-width: 768px) {
.container-width {
max-width: 792px;
}
.show{
display:none;
}
}
@media (min-width: 1024px) {
.container-width {
max-width: 792px;
}
}
@media (min-width: 768px){
.show{
display: block;
visibility: visible;
}
}
@media (max-width:640px){
.show{
visibility: hidden;
display:none;
}
}
`}
</style>
</Head>
<Tailwind>
<Body
className="container-width mx-auto"
style={{ fontFamily: "inter" }}
>
<Container>
<div className="bg-[#E1D6D666] p-4">
<Img
className="mx-auto"
src="/public/images/logo-text.svg"
alt="Logo"
/>
</div>

<div className="p-10">
<Section>
<Img
className="mx-auto"
src="/public/images/money-transfer-email.png"
alt="money-transfer-invoice"
/>

<Heading className="show py-8 text-center text-2xl font-semibold">
Invoice
</Heading>

<Text className="pt-4 font-semibold text-[#0A0A0A]">
Hi John Doe,
</Text>

<Text className="text-[#111111]">
We hope you are doing well. Thank you for your recent
purchase from Boilerplate. Please find your invoice attached
to this email.
</Text>
</Section>

<div>
<DetailTable
title="Invoice Details"
text=""
details={invoiceDetails}
/>
<OrderSummaryTable
title="Order Summary"
details={orderSummary}
/>
<DetailTable
title="Payment Details"
text="Please ensure to pay into this account within two days from today."
details={paymentDetails}
/>

<div className="py-6">
<Link>
<Button className="align-center mx-auto flex w-[142px] justify-center rounded-lg bg-[#F97316] px-[8px] py-[10px] font-bold text-[#FAF8F8]">
Pay Now
</Button>
</Link>
</div>
</div>

<Section>
<Text>Have any questions about your order?</Text>
<Text>
Give us a call at (+234){phone} or Email us at {email}
</Text>

<div>
<Text>
Regards, <br />
Boilerplate
</Text>
{/* <Text>Boilerplate</Text> */}
</div>
</Section>
</div>

<EmailFooter />
</Container>
</Body>
</Tailwind>
</Html>
</>
);
};

export default InvoiceEmail;
33 changes: 33 additions & 0 deletions app/email/templates/invoice-email-temp/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export interface Detail {
id: number;
label: string;
value: string;
}

export const invoiceDetails: Detail[] = [
{ id: 1, label: "Invoice Number", value: "#EJ78465" },
{ id: 2, label: "Date of Issue", value: "July 17, 2024" },
{ id: 3, label: "Due Date", value: "July 19, 2024" },
];

export const paymentDetails: Detail[] = [
{ id: 1, label: "Amount", value: "$352" },
{ id: 2, label: "Payment Method", value: "Bank" },
{ id: 3, label: "Bank Name", value: " United Bank of Africa" },
{ id: 4, label: "Account Number", value: "2108689490" },
{ id: 5, label: "Account Name", value: "John Doe" },
];

export interface OrderDetail {
id: number;
label: string;
value: string;
amt: string;
}

export const orderSummary: OrderDetail[] = [
{ id: 1, label: "Item", value: "5", amt: "$450.00" },
{ id: 2, label: "Item", value: "5", amt: "$50.00" },
{ id: 3, label: "VAT", value: "10%", amt: "$500.00" },
{ id: 4, label: "TOTAL", value: "100%", amt: "$500.00" },
];
16 changes: 4 additions & 12 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ import {
Outlet,
Scripts,
ScrollRestoration,
useLocation,
} from "@remix-run/react";
import type { ReactNode } from "react";

import FooterLight from "./components/ui/footerLight";
import Header from "./components/ui/header";
import { AdminSideNavBar } from "./components/SuperAdminSideBar/SuperAdminSideNavBar";
import styles from "./styles/global.css?url";

export const links: LinksFunction = () => [
Expand All @@ -20,9 +18,6 @@ export const links: LinksFunction = () => [
];

export function Layout({ children }: { children: ReactNode }) {
const location = useLocation();
const pagesWithNoFooter = ["/dashboard/password-settings"];
const showFooter = !pagesWithNoFooter.includes(location.pathname);
return (
<html lang="en">
<head>
Expand All @@ -32,12 +27,9 @@ export function Layout({ children }: { children: ReactNode }) {
<Links />
</head>
<body>
<div>
<main>
<Header />
{children}
{showFooter && <FooterLight />}
</main>
<div className="flex">
<AdminSideNavBar />
<main className="flex-1">{children}</main>,
<ScrollRestoration />
<Scripts />
</div>
Expand Down
Loading

0 comments on commit 7a56cfd

Please sign in to comment.