Dental Care

This commit is contained in:
Iliyan Angelov
2025-11-16 14:29:51 +02:00
commit 39077550ef
194 changed files with 43197 additions and 0 deletions

View File

@@ -0,0 +1,358 @@
import * as React from "react";
export interface ServiceItem {
description: string;
qty: number;
unitPrice: number;
total: number;
}
export interface DentalInvoiceProps {
invoiceNumber: string;
invoiceDate: string;
dueDate: string;
patientName: string;
patientAddress: string;
patientCity: string;
patientPhone: string;
patientEmail: string;
bookingId: string;
appointmentDate: string;
appointmentTime: string;
doctorName: string;
treatmentRoom: string;
appointmentDuration: string;
reasonForVisit: string;
pdfDownloadUrl: string;
paymentStatus: string;
nextAppointmentDate: string;
nextAppointmentTime: string;
nextAppointmentPurpose: string;
services: ServiceItem[];
subtotal: number;
tax: number;
totalDue: number;
}
import {
Html,
Head,
Body,
Container,
Section,
Row,
Column,
Text,
Heading,
Hr,
Button,
Tailwind,
} from "@react-email/components";
const DentalInvoice: React.FC<DentalInvoiceProps> = (props) => {
return (
<Html lang="en" dir="ltr">
<Tailwind>
<Head />
<Body className="bg-gray-100 font-sans py-[40px]">
<Container className="bg-white max-w-[600px] mx-auto rounded-[8px] shadow-lg">
{/* Header */}
<Section className="bg-blue-600 text-white p-[32px] rounded-t-[8px]">
<Heading className="text-[28px] font-bold m-0 text-center">
DENTAL U CARE
</Heading>
<Text className="text-[16px] text-center m-0 mt-[8px] opacity-90">
Professional Dental Services
</Text>
</Section>
{/* Invoice Header */}
<Section className="p-[32px]">
<Row>
<Column>
<Heading className="text-[24px] font-bold text-gray-800 m-0">
INVOICE
</Heading>
<Text className="text-[14px] text-gray-600 m-0 mt-[4px]">
Invoice #: {props.invoiceNumber}
</Text>
<Text className="text-[14px] text-gray-600 m-0">
Date: {props.invoiceDate}
</Text>
<Text className="text-[14px] text-gray-600 m-0">
Due Date: {props.dueDate}
</Text>
</Column>
<Column align="right">
<Text className="text-[14px] text-gray-600 m-0 font-semibold">
Dental U Care Clinic
</Text>
<Text className="text-[14px] text-gray-600 m-0">
Baltan Street
</Text>
<Text className="text-[14px] text-gray-600 m-0">
Puerto Princesa City, Palawan 5300
</Text>
<Text className="text-[14px] text-gray-600 m-0">
Phone: (043) 756-1234
</Text>
</Column>
</Row>
</Section>
<Hr className="border-gray-200 mx-[32px]" />
{/* Patient Information */}
<Section className="px-[32px] py-[24px]">
<Heading className="text-[18px] font-semibold text-gray-800 m-0 mb-[16px]">
Bill To:
</Heading>
<Text className="text-[14px] text-gray-700 m-0 font-semibold">
{props.patientName}
</Text>
<Text className="text-[14px] text-gray-600 m-0">
{props.patientAddress}
</Text>
<Text className="text-[14px] text-gray-600 m-0">
{props.patientCity}
</Text>
<Text className="text-[14px] text-gray-600 m-0">
Phone: {props.patientPhone}
</Text>
<Text className="text-[14px] text-gray-600 m-0">
Email: {props.patientEmail}
</Text>
</Section>
<Hr className="border-gray-200 mx-[32px]" />
{/* Booking Details */}
<Section className="px-[32px] py-[24px] bg-blue-50 mx-[32px] rounded-[8px]">
<Heading className="text-[18px] font-semibold text-gray-800 m-0 mb-[16px]">
Appointment Details:
</Heading>
<Row>
<Column className="w-[50%]">
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Booking ID:</strong> {props.bookingId}
</Text>
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Appointment Date:</strong> {props.appointmentDate}
</Text>
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Time:</strong> {props.appointmentTime}
</Text>
</Column>
<Column className="w-[50%]">
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Doctor:</strong> {props.doctorName}
</Text>
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Treatment Room:</strong> {props.treatmentRoom}
</Text>
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Duration:</strong> {props.appointmentDuration}
</Text>
</Column>
</Row>
<Text className="text-[14px] text-gray-700 m-0 mt-[12px]">
<strong>Reason for Visit:</strong> {props.reasonForVisit}
</Text>
</Section>
<Hr className="border-gray-200 mx-[32px] my-[24px]" />
{/* Services Table */}
<Section className="px-[32px] py-[24px]">
<Heading className="text-[18px] font-semibold text-gray-800 m-0 mb-[16px]">
Services Rendered:
</Heading>
{/* Table Header */}
<Row className="bg-gray-50 border-solid border-[1px] border-gray-200">
<Column className="p-[12px] w-[50%]">
<Text className="text-[14px] font-semibold text-gray-700 m-0">
Description
</Text>
</Column>
<Column className="p-[12px] w-[15%] text-center">
<Text className="text-[14px] font-semibold text-gray-700 m-0">
Qty
</Text>
</Column>
<Column className="p-[12px] w-[20%] text-center">
<Text className="text-[14px] font-semibold text-gray-700 m-0">
Unit Price
</Text>
</Column>
<Column className="p-[12px] w-[15%] text-center">
<Text className="text-[14px] font-semibold text-gray-700 m-0">
Total
</Text>
</Column>
</Row>
{/* Dynamic Service Items */}
{props.services.map((service, index) => (
<Row
key={index}
className="border-solid border-[1px] border-t-0 border-gray-200"
>
<Column className="p-[12px] w-[50%]">
<Text className="text-[14px] text-gray-700 m-0">
{service.description}
</Text>
</Column>
<Column className="p-[12px] w-[15%] text-center">
<Text className="text-[14px] text-gray-700 m-0">
{service.qty}
</Text>
</Column>
<Column className="p-[12px] w-[20%] text-center">
<Text className="text-[14px] text-gray-700 m-0">
{service.unitPrice.toFixed(2)}
</Text>
</Column>
<Column className="p-[12px] w-[15%] text-center">
<Text className="text-[14px] text-gray-700 m-0">
{service.total.toFixed(2)}
</Text>
</Column>
</Row>
))}
</Section>
{/* Totals */}
<Section className="px-[32px]">
<Row>
<Column className="w-[70%]"></Column>
<Column className="w-[30%]">
<Row className="mb-[8px]">
<Column className="w-[60%]">
<Text className="text-[14px] text-gray-700 m-0">
Subtotal:
</Text>
</Column>
<Column className="w-[40%] text-right">
<Text className="text-[14px] text-gray-700 m-0">
{props.subtotal.toFixed(2)}
</Text>
</Column>
</Row>
<Row className="mb-[8px]">
<Column className="w-[60%]">
<Text className="text-[14px] text-gray-700 m-0">
Tax (12%):
</Text>
</Column>
<Column className="w-[40%] text-right">
<Text className="text-[14px] text-gray-700 m-0">
{props.tax.toFixed(2)}
</Text>
</Column>
</Row>
<Hr className="border-gray-300 my-[8px]" />
<Row>
<Column className="w-[60%]">
<Text className="text-[16px] font-bold text-gray-800 m-0">
Total Due:
</Text>
</Column>
<Column className="w-[40%] text-right">
<Text className="text-[16px] font-bold text-blue-600 m-0">
{props.totalDue.toFixed(2)}
</Text>
</Column>
</Row>
</Column>
</Row>
</Section>
{/* Download PDF Button */}
<Section className="px-[32px] py-[24px] text-center">
<Button
href={props.pdfDownloadUrl}
className="box-border bg-blue-600 text-white px-[32px] py-[16px] rounded-[8px] text-[16px] font-semibold no-underline inline-block"
>
📄 Download PDF Invoice
</Button>
<Text className="text-[12px] text-gray-500 m-0 mt-[12px]">
Click the button above to download a PDF copy of this invoice
</Text>
</Section>
{/* Payment Information */}
<Section className="px-[32px] py-[24px] bg-green-50 mx-[32px] my-[24px] rounded-[8px]">
<Heading className="text-[16px] font-semibold text-gray-800 m-0 mb-[12px]">
Payment Information
</Heading>
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Payment Status:</strong> {props.paymentStatus}
</Text>
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Payment Methods:</strong> Cash, Credit Card, Bank
Transfer, GCash, PayMaya
</Text>
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Bank Details:</strong> BPI - Account #1234567890 (Dental
U Care Clinic)
</Text>
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>GCash:</strong> 09171234567
</Text>
<Text className="text-[14px] text-gray-700 m-0">
<strong>Payment Terms:</strong> Payment due within 30 days of
invoice date
</Text>
</Section>
{/* Next Appointment */}
<Section className="px-[32px] py-[24px] bg-yellow-50 mx-[32px] rounded-[8px]">
<Heading className="text-[16px] font-semibold text-gray-800 m-0 mb-[12px]">
Next Appointment Reminder
</Heading>
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Follow-up Date:</strong> {props.nextAppointmentDate}
</Text>
<Text className="text-[14px] text-gray-700 m-0 mb-[8px]">
<strong>Time:</strong> {props.nextAppointmentTime}
</Text>
<Text className="text-[14px] text-gray-700 m-0">
<strong>Purpose:</strong> {props.nextAppointmentPurpose}
</Text>
</Section>
{/* Footer */}
<Section className="px-[32px] py-[24px] text-center border-t-[1px] border-solid border-gray-200">
<Text className="text-[14px] text-gray-600 m-0 mb-[8px]">
Thank you for choosing Dental U Care for your oral health needs!
</Text>
<Text className="text-[12px] text-gray-500 m-0 mb-[8px]">
For questions about this invoice, please contact us at
billing@dentalucare.com or (043) 756-1234
</Text>
<Text className="text-[12px] text-gray-500 m-0">
To reschedule or cancel appointments, call us at least 24 hours
in advance
</Text>
</Section>
{/* Company Footer */}
<Section className="px-[32px] py-[16px] bg-gray-50 text-center rounded-b-[8px]">
<Text className="text-[12px] text-gray-500 m-0">
Dental U Care Clinic | Baltan Street, Puerto Princesa City, Palawan
5300
</Text>
<Text className="text-[12px] text-gray-500 m-0">
© 2025 Dental U Care. All rights reserved. | License
#DC-2025-001
</Text>
</Section>
</Container>
</Body>
</Tailwind>
</Html>
);
};
export default DentalInvoice;

View File

@@ -0,0 +1,198 @@
import * as React from "react";
import {
Body,
Container,
Head,
Heading,
Html,
Preview,
Section,
Text,
Tailwind,
Row,
Column,
Hr,
} from "@react-email/components";
interface DentalAppointmentReminderProps {
patientName: string;
appointmentDate: string;
appointmentTime: string;
doctorName: string;
treatmentType: string;
duration: string;
clinicPhone: string;
clinicEmail: string;
clinicAddress: string;
}
interface DentalAppointmentReminderComponent
extends React.FC<DentalAppointmentReminderProps> {
PreviewProps?: DentalAppointmentReminderProps;
}
const DentalAppointmentReminder: DentalAppointmentReminderComponent = (
props: DentalAppointmentReminderProps
) => {
return (
<Html lang="en" dir="ltr">
<Tailwind>
<Head />
<Preview>
Your upcoming appointment at Dental U Care - {props.appointmentDate}
</Preview>
<Body className="bg-gray-100 font-sans py-[40px]">
<Container className="bg-white rounded-[8px] shadow-lg max-w-[600px] mx-auto p-[40px]">
{/* Header */}
<Section className="text-center mb-[32px]">
<Heading className="text-[28px] font-bold text-blue-600 m-0 mb-[8px]">
Dental U Care
</Heading>
<Text className="text-[16px] text-gray-600 m-0">
Your Smile, Our Priority
</Text>
</Section>
{/* Main Content */}
<Section className="mb-[32px]">
<Heading className="text-[24px] font-bold text-gray-800 mb-[16px]">
Appointment Reminder
</Heading>
<Text className="text-[16px] text-gray-700 mb-[24px] leading-[24px]">
Dear {props.patientName},
</Text>
<Text className="text-[16px] text-gray-700 mb-[24px] leading-[24px]">
This is a friendly reminder about your upcoming dental
appointment at Dental U Care.
</Text>
</Section>
{/* Appointment Details */}
<Section className="bg-blue-50 rounded-[8px] p-[24px] mb-[32px]">
<Heading className="text-[20px] font-bold text-blue-800 mb-[16px]">
Appointment Details
</Heading>
<Row className="mb-[12px]">
<Column className="w-[120px]">
<Text className="text-[14px] font-semibold text-gray-600 m-0">
Date:
</Text>
</Column>
<Column>
<Text className="text-[14px] text-gray-800 m-0">
{props.appointmentDate}
</Text>
</Column>
</Row>
<Row className="mb-[12px]">
<Column className="w-[120px]">
<Text className="text-[14px] font-semibold text-gray-600 m-0">
Time:
</Text>
</Column>
<Column>
<Text className="text-[14px] text-gray-800 m-0">
{props.appointmentTime}
</Text>
</Column>
</Row>
<Row className="mb-[12px]">
<Column className="w-[120px]">
<Text className="text-[14px] font-semibold text-gray-600 m-0">
Doctor:
</Text>
</Column>
<Column>
<Text className="text-[14px] text-gray-800 m-0">
{props.doctorName}
</Text>
</Column>
</Row>
<Row className="mb-[12px]">
<Column className="w-[120px]">
<Text className="text-[14px] font-semibold text-gray-600 m-0">
Treatment:
</Text>
</Column>
<Column>
<Text className="text-[14px] text-gray-800 m-0">
{props.treatmentType}
</Text>
</Column>
</Row>
<Row>
<Column className="w-[120px]">
<Text className="text-[14px] font-semibold text-gray-600 m-0">
Duration:
</Text>
</Column>
<Column>
<Text className="text-[14px] text-gray-800 m-0">
{props.duration}
</Text>
</Column>
</Row>
</Section>
{/* Important Notes */}
<Section className="mb-[32px]">
<Heading className="text-[18px] font-bold text-gray-800 mb-[16px]">
Important Reminders
</Heading>
<Text className="text-[14px] text-gray-700 mb-[8px] leading-[20px]">
Please arrive 10 minutes early for check-in
</Text>
<Text className="text-[14px] text-gray-700 mb-[8px] leading-[20px]">
Bring a valid ID and insurance card
</Text>
<Text className="text-[14px] text-gray-700 mb-[8px] leading-[20px]">
If you need to reschedule, please call us at least 24 hours in
advance
</Text>
<Text className="text-[14px] text-gray-700 mb-[8px] leading-[20px]">
Continue your regular oral hygiene routine before your visit
</Text>
</Section>
{/* Contact Information */}
<Section className="mb-[32px]">
<Heading className="text-[18px] font-bold text-gray-800 mb-[16px]">
Need to Make Changes?
</Heading>
<Text className="text-[16px] text-gray-700 mb-[16px] leading-[24px]">
If you need to reschedule or cancel your appointment, please
contact us:
</Text>
<Text className="text-[16px] text-blue-600 font-semibold mb-[8px]">
Phone: {props.clinicPhone}
</Text>
<Text className="text-[16px] text-blue-600 font-semibold mb-[16px]">
Email: {props.clinicEmail}
</Text>
</Section>
<Hr className="border-gray-300 mb-[32px]" />
{/* Footer */}
<Section className="text-center">
<Text className="text-[14px] text-gray-600 mb-[8px]">
Dental U Care
</Text>
<Text className="text-[14px] text-gray-600 mb-[8px] m-0">
{props.clinicAddress}
</Text>
<Text className="text-[14px] text-gray-600 mb-[16px]">
Phone: {props.clinicPhone} | Email: {props.clinicEmail}
</Text>
<Text className="text-[12px] text-gray-500 m-0">
© {new Date().getFullYear()} Dental U Care. All rights
reserved.
</Text>
</Section>
</Container>
</Body>
</Tailwind>
</Html>
);
};
export default DentalAppointmentReminder;

View File

@@ -0,0 +1,115 @@
import * as React from "react";
import {
Html,
Head,
Body,
Container,
Section,
Text,
Button,
Hr,
Tailwind,
} from "@react-email/components";
interface VerificationEmailProps {
username ?: string;
verificationUrl?: string;
}
const VerificationEmail = (props: VerificationEmailProps) => {
const { username, verificationUrl } = props;
return (
<Html lang="en" dir="ltr">
<Tailwind>
<Head />
<Body className="bg-gray-100 font-sans py-[40px]">
<Container className="bg-white rounded-[8px] shadow-lg max-w-[600px] mx-auto p-[40px]">
{/* Header */}
<Section className="text-center mb-[32px]">
<Text className="text-[32px] font-bold text-blue-600 m-0 mb-[8px]">
Dental U Care
</Text>
<Text className="text-[16px] text-gray-600 m-0">
Your Trusted Dental Care Partner
</Text>
</Section>
{/* Main Content */}
<Section>
<Text className="text-[24px] font-bold text-gray-800 mb-[24px] m-0">
Verify Your Email Address
</Text>
<Text className="text-[16px] text-gray-700 mb-[24px] m-0 leading-[24px]">
Thank you {username} for choosing Dental U Care! To complete your account
setup and ensure secure access to your dental care portal,
please verify your email address by clicking the button below.
</Text>
{/* Verification Button */}
<Section className="text-center my-[32px]">
<Button
href={verificationUrl}
className="bg-blue-600 text-white px-[32px] py-[16px] rounded-[8px] text-[16px] font-semibold no-underline box-border hover:bg-blue-700 transition-colors"
>
Verify Email Address
</Button>
</Section>
<Text className="text-[14px] text-gray-600 mb-[24px] m-0 leading-[20px]">
If the button above doesn`t work, you can also copy and paste
this link into your browser:
</Text>
<Text className="text-[14px] text-blue-600 mb-[32px] m-0 break-all">
{verificationUrl}
</Text>
<Text className="text-[16px] text-gray-700 mb-[24px] m-0 leading-[24px]">
This verification link will expire in 24 hours for your
security. If you didn`t create an account with Dental U Care,
please ignore this email.
</Text>
</Section>
<Hr className="border-gray-200 my-[32px]" />
{/* Footer */}
<Section>
<Text className="text-[14px] text-gray-600 mb-[16px] m-0">
Need help? Contact our support team at{" "}
<a
href="mailto:support@dentalucare.com"
className="text-blue-600 no-underline"
>
send@dentalucare.tech
</a>{" "}
or call us at (+63) 917-123-4567.
</Text>
<Text className="text-[12px] text-gray-500 m-0 mb-[8px]">
Dental U Care Clinic
</Text>
<Text className="text-[12px] text-gray-500 m-0 mb-[8px]">
Baltan Street, Barangay San Miguel
</Text>
<Text className="text-[12px] text-gray-500 m-0 mb-[16px]">
Puerto Princesa, Palawan, Philippines
</Text>
<Text className="text-[12px] text-gray-500 m-0">
© 2025 Dental U Care. All rights reserved.{" "}
<a href="#" className="text-blue-600 no-underline">
Unsubscribe
</a>
</Text>
</Section>
</Container>
</Body>
</Tailwind>
</Html>
);
};
export default VerificationEmail;

View File

@@ -0,0 +1,134 @@
import * as React from "react";
import {
Html,
Head,
Body,
Container,
Section,
Text,
Button,
Hr,
Tailwind,
} from "@react-email/components";
interface ForgotPasswordEmailProps {
username?: string;
resetUrl?: string;
userEmail?: string;
}
const ForgotPasswordEmail = (props: ForgotPasswordEmailProps) => {
const { username, resetUrl, userEmail } = props;
return (
<Html lang="en" dir="ltr">
<Tailwind>
<Head />
<Body className="bg-gray-100 font-sans py-[40px]">
<Container className="bg-white rounded-[8px] shadow-lg max-w-[600px] mx-auto p-[40px]">
{/* Header */}
<Section className="text-center mb-[32px]">
<Text className="text-[32px] font-bold text-blue-600 m-0 mb-[8px]">
Dental U Care
</Text>
<Text className="text-[16px] text-gray-600 m-0">
Your Trusted Dental Care Partner
</Text>
</Section>
{/* Main Content */}
<Section>
<Text className="text-[24px] font-bold text-gray-800 mb-[24px] m-0">
Reset Your Password
</Text>
<Text className="text-[16px] text-gray-700 mb-[24px] m-0 leading-[24px]">
Hello {username}
</Text>
<Text className="text-[16px] text-gray-700 mb-[24px] m-0 leading-[24px]">
We received a request to reset the password for your {userEmail} Dental U
Care account. Don`t worry - it happens to the best of us! Click
the button below to create a new password.
</Text>
{/* Reset Password Button */}
<Section className="text-center my-[32px]">
<Button
href={resetUrl}
className="bg-green-600 text-white px-[32px] py-[16px] rounded-[8px] text-[16px] font-semibold no-underline box-border hover:bg-green-700 transition-colors"
>
Reset Password
</Button>
</Section>
<Text className="text-[14px] text-gray-600 mb-[24px] m-0 leading-[20px]">
If the button above doesn`t work, you can also copy and paste
this link into your browser:
</Text>
<Text className="text-[14px] text-blue-600 mb-[32px] m-0 break-all">
{resetUrl}
</Text>
<Section className="bg-yellow-50 border-l-[4px] border-yellow-400 p-[16px] mb-[24px] rounded-[4px]">
<Text className="text-[14px] text-yellow-800 m-0 font-semibold mb-[8px]">
Important Security Information:
</Text>
<Text className="text-[14px] text-yellow-700 m-0 leading-[20px]">
This reset link will expire in 1 hour for your security
<br />
If you didn`t request this password reset, please ignore
this email
<br />• Your current password will remain unchanged until you
create a new one
</Text>
</Section>
<Text className="text-[16px] text-gray-700 mb-[24px] m-0 leading-[24px]">
For your account security, we recommend choosing a strong
password that includes a mix of letters, numbers, and special
characters.
</Text>
</Section>
<Hr className="border-gray-200 my-[32px]" />
{/* Footer */}
<Section>
<Text className="text-[14px] text-gray-600 mb-[16px] m-0">
Having trouble? Our support team is here to help at{" "}
<a
href="mailto:info@dentalucare.com"
className="text-blue-600 no-underline"
>
info@dentalucare.com
</a>{" "}
or call us at (+63) 917-123-4567.
</Text>
<Text className="text-[12px] text-gray-500 m-0 mb-[8px]">
Dental U Care
</Text>
<Text className="text-[12px] text-gray-500 m-0 mb-[8px]">
Baltan Street, Barangay San Miguel
</Text>
<Text className="text-[12px] text-gray-500 m-0 mb-[16px]">
Puerto Princesa, Palawan, Philippines
</Text>
<Text className="text-[12px] text-gray-500 m-0">
© 2025 Dental U Care. All rights reserved.{" "}
<a href="#" className="text-blue-600 no-underline">
Unsubscribe
</a>
</Text>
</Section>
</Container>
</Body>
</Tailwind>
</Html>
);
};
export default ForgotPasswordEmail;