From 4794fd3fbac782a5c03d164d9e3521b54d375c3f Mon Sep 17 00:00:00 2001 From: Chisom92 Date: Wed, 27 May 2026 11:55:58 +0000 Subject: [PATCH] Implement dental records page and enhance contact page --- .gitignore | 5 +- wata-board-frontend/src/App.tsx | 2 + wata-board-frontend/src/lib/api/dentalAPI.ts | 229 ++++++ wata-board-frontend/src/pages/Contact.tsx | 224 ++++-- .../src/pages/DentalRecords.tsx | 689 ++++++++++++++++++ 5 files changed, 1089 insertions(+), 60 deletions(-) create mode 100644 wata-board-frontend/src/lib/api/dentalAPI.ts create mode 100644 wata-board-frontend/src/pages/DentalRecords.tsx diff --git a/.gitignore b/.gitignore index 62860276..31b96fb1 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,7 @@ performance/results/*.md next-env.d.ts -bun.lock \ No newline at end of file +bun.lock + +# somzilla issues file +/somzilla.md \ No newline at end of file diff --git a/wata-board-frontend/src/App.tsx b/wata-board-frontend/src/App.tsx index 82315f18..dda50262 100644 --- a/wata-board-frontend/src/App.tsx +++ b/wata-board-frontend/src/App.tsx @@ -17,6 +17,7 @@ import About from './pages/About'; import Contact from './pages/Contact'; import Rate from './pages/Rate'; import ScheduledPayments from './pages/ScheduledPayments'; +import DentalRecords from './pages/DentalRecords'; import { WalletBalance } from './components/WalletBalance'; import { useWalletBalance } from './hooks/useWalletBalance'; import { useFeeEstimation } from './hooks/useFeeEstimation'; @@ -358,6 +359,7 @@ export default function App() { } /> } /> } /> + } /> diff --git a/wata-board-frontend/src/lib/api/dentalAPI.ts b/wata-board-frontend/src/lib/api/dentalAPI.ts new file mode 100644 index 00000000..a29fc25e --- /dev/null +++ b/wata-board-frontend/src/lib/api/dentalAPI.ts @@ -0,0 +1,229 @@ +// ─── Types ────────────────────────────────────────────────────────────────── + +export type ToothStatus = 'healthy' | 'cavity' | 'missing' | 'treated' | 'fractured' | 'tartar'; +export type IssueSeverity = 'mild' | 'moderate' | 'severe'; +export type IssueStatus = 'active' | 'monitoring' | 'resolved'; +export type ReminderType = 'cleaning' | 'exam' | 'follow_up' | 'medication'; + +export interface ToothRecord { + toothId: number; + label: string; + status: ToothStatus; + notes?: string; + lastUpdated: string; +} + +export interface DentalExam { + id: string; + petId: string; + date: string; + vetName: string; + clinic: string; + overallScore: number; + plaqueLevel: 'none' | 'mild' | 'moderate' | 'severe'; + tartarLevel: 'none' | 'mild' | 'moderate' | 'severe'; + gingivitisLevel: 'none' | 'mild' | 'moderate' | 'severe'; + notes: string; + toothChart: ToothRecord[]; + nextExamDate: string; +} + +export interface CleaningRecord { + id: string; + petId: string; + date: string; + vetName: string; + clinic: string; + type: 'professional' | 'home'; + anesthesiaUsed: boolean; + teethExtracted: number[]; + notes: string; + cost?: number; +} + +export interface DentalIssue { + id: string; + petId: string; + toothId?: number; + issueType: string; + severity: IssueSeverity; + status: IssueStatus; + diagnosedDate: string; + resolvedDate?: string; + treatment?: string; + notes: string; +} + +export interface DentalReminder { + id: string; + petId: string; + type: ReminderType; + title: string; + description: string; + dueDate: string; + isCompleted: boolean; + completedDate?: string; +} + +// ─── Mock data ─────────────────────────────────────────────────────────────── + +const buildDefaultToothChart = (): ToothRecord[] => { + const statuses: ToothStatus[] = [ + 'healthy', 'healthy', 'healthy', 'tartar', 'healthy', + 'cavity', 'healthy', 'healthy', 'healthy', 'missing', + 'healthy', 'treated', + ]; + return Array.from({ length: 42 }, (_, i) => ({ + toothId: i + 1, + label: `T${i + 1}`, + status: i < statuses.length ? statuses[i] : 'healthy', + lastUpdated: '2024-12-15', + })); +}; + +export const MOCK_DENTAL_EXAMS: DentalExam[] = [ + { + id: 'exam-001', + petId: 'pet-001', + date: '2025-01-15', + vetName: 'Dr. Sarah Chen', + clinic: 'PawsCare Veterinary Clinic', + overallScore: 7, + plaqueLevel: 'mild', + tartarLevel: 'moderate', + gingivitisLevel: 'none', + notes: 'Good overall dental health. Some tartar buildup on molars. Professional cleaning recommended within 3 months.', + toothChart: buildDefaultToothChart(), + nextExamDate: '2025-07-15', + }, + { + id: 'exam-002', + petId: 'pet-001', + date: '2024-07-10', + vetName: 'Dr. James Miller', + clinic: 'Happy Tails Animal Hospital', + overallScore: 6, + plaqueLevel: 'moderate', + tartarLevel: 'moderate', + gingivitisLevel: 'mild', + notes: 'Plaque accumulation noted on upper premolars. Recommend daily brushing and dental chews.', + toothChart: buildDefaultToothChart(), + nextExamDate: '2025-01-10', + }, +]; + +export const MOCK_CLEANINGS: CleaningRecord[] = [ + { + id: 'clean-001', + petId: 'pet-001', + date: '2025-02-01', + vetName: 'Dr. Sarah Chen', + clinic: 'PawsCare Veterinary Clinic', + type: 'professional', + anesthesiaUsed: true, + teethExtracted: [], + notes: 'Full scaling and polishing performed. No extractions needed. Healing well.', + cost: 420, + }, + { + id: 'clean-002', + petId: 'pet-001', + date: '2024-08-20', + vetName: 'Dr. James Miller', + clinic: 'Happy Tails Animal Hospital', + type: 'professional', + anesthesiaUsed: true, + teethExtracted: [10], + notes: 'Scaling completed. Tooth #10 (lower left molar) extracted due to severe decay.', + cost: 580, + }, + { + id: 'clean-003', + petId: 'pet-001', + date: '2025-01-10', + vetName: 'Owner', + clinic: 'Home', + type: 'home', + anesthesiaUsed: false, + teethExtracted: [], + notes: 'Daily brushing routine maintained. Used enzymatic toothpaste.', + cost: 0, + }, +]; + +export const MOCK_ISSUES: DentalIssue[] = [ + { + id: 'issue-001', + petId: 'pet-001', + toothId: 6, + issueType: 'Cavity', + severity: 'moderate', + status: 'active', + diagnosedDate: '2025-01-15', + treatment: 'Dental filling scheduled for next visit', + notes: 'Small cavity on tooth #6. Monitor closely. Scheduled for treatment.', + }, + { + id: 'issue-002', + petId: 'pet-001', + toothId: 4, + issueType: 'Tartar Buildup', + severity: 'mild', + status: 'monitoring', + diagnosedDate: '2024-07-10', + treatment: 'Daily brushing and dental chews', + notes: 'Tartar on upper premolars improving with home care routine.', + }, + { + id: 'issue-003', + petId: 'pet-001', + toothId: 10, + issueType: 'Tooth Decay', + severity: 'severe', + status: 'resolved', + diagnosedDate: '2024-06-05', + resolvedDate: '2024-08-20', + treatment: 'Tooth extraction', + notes: 'Severe decay led to extraction. Area healed successfully.', + }, +]; + +export const MOCK_REMINDERS: DentalReminder[] = [ + { + id: 'rem-001', + petId: 'pet-001', + type: 'exam', + title: '6-Month Dental Exam Due', + description: 'Schedule annual dental exam with Dr. Sarah Chen at PawsCare.', + dueDate: '2025-07-15', + isCompleted: false, + }, + { + id: 'rem-002', + petId: 'pet-001', + type: 'cleaning', + title: 'Professional Cleaning', + description: 'Book follow-up cleaning session as recommended by vet.', + dueDate: '2025-05-01', + isCompleted: false, + }, + { + id: 'rem-003', + petId: 'pet-001', + type: 'follow_up', + title: 'Cavity Follow-up', + description: 'Return to clinic for filling on tooth #6.', + dueDate: '2025-03-10', + isCompleted: false, + }, + { + id: 'rem-004', + petId: 'pet-001', + type: 'cleaning', + title: 'Home Brushing Session', + description: 'Daily enzymatic toothbrush routine.', + dueDate: '2025-02-21', + isCompleted: true, + completedDate: '2025-02-20', + }, +]; diff --git a/wata-board-frontend/src/pages/Contact.tsx b/wata-board-frontend/src/pages/Contact.tsx index cd90a645..46588819 100644 --- a/wata-board-frontend/src/pages/Contact.tsx +++ b/wata-board-frontend/src/pages/Contact.tsx @@ -1,4 +1,11 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; + +interface FormErrors { + name?: string; + email?: string; + subject?: string; + message?: string; +} function Contact() { const [formData, setFormData] = useState({ @@ -7,120 +14,219 @@ function Contact() { subject: '', message: '' }); + const [errors, setErrors] = useState({}); const [submitted, setSubmitted] = useState(false); + const [submitError, setSubmitError] = useState(''); + const [openFaq, setOpenFaq] = useState(null); + + const validateForm = (): boolean => { + const newErrors: FormErrors = {}; + if (!formData.name.trim()) newErrors.name = 'Name is required'; + if (!formData.email.trim()) newErrors.email = 'Email is required'; + else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) newErrors.email = 'Please enter a valid email address'; + if (!formData.subject) newErrors.subject = 'Please select a subject'; + if (!formData.message.trim()) newErrors.message = 'Message is required'; + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - console.log('Form submitted:', formData); - setSubmitted(true); - setTimeout(() => setSubmitted(false), 3000); + setSubmitError(''); + if (!validateForm()) return; + try { + console.log('Form submitted:', formData); + setSubmitted(true); + setFormData({ name: '', email: '', subject: '', message: '' }); + setErrors({}); + setTimeout(() => setSubmitted(false), 4000); + } catch (err) { + setSubmitError('Something went wrong. Please try again later.'); + } }; const handleChange = (e: React.ChangeEvent) => { - setFormData(prev => ({ - ...prev, - [e.target.name]: e.target.value - })); + const { name, value } = e.target; + setFormData(prev => ({ ...prev, [name]: value })); + if (errors[name as keyof FormErrors]) { + setErrors(prev => ({ ...prev, [name]: undefined })); + } }; + const faqItems = [ + { q: 'How do I connect my Freighter wallet?', a: 'Install the Freighter browser extension, create or import a wallet, then click "Connect Wallet" on our homepage and approve the connection.' }, + { q: 'What networks does Wata-Board support?', a: 'Wata-Board supports the Stellar network on both public mainnet and testnet for testing purposes.' }, + { q: 'How long do transactions take?', a: 'Stellar transactions typically complete within 3-5 seconds, making it ideal for fast utility payments.' }, + { q: 'Is there any fee for using the service?', a: 'Only minimal Stellar network fees (in XLM) are charged. Fee estimates are shown before confirming transactions.' }, + { q: 'Can I schedule recurring payments?', a: 'Yes! Use the "Scheduled Payments" feature to set up automatic recurring payments. Manage or cancel anytime from the Schedules page.' } + ]; + return (

Contact Us

-
-
-

- Have questions or feedback? We'd love to hear from you. Fill out the form - and our team will get back to you as soon as possible. -

- -
-
-
- - - +
+
+

+ Have questions or feedback? We'd love to hear from you. Fill out the form + and our team will get back to you as soon as possible. +

+ +
+
+
+ + + +
+ support@wata-board.com +
+ +
+
+ + + + +
+ Blockchain City, Stellar Network
- support@wata-board.com
+
-
-
- - - + {/* Social Links */} +
-
+ {/* FAQ Section */} +
+

Frequently Asked Questions

+
+ {faqItems.map((item, idx) => ( +
+ + {openFaq === idx && ( +
+ {item.a} +
+ )} +
+ ))} +
+
+
+ {/* Right column: Form */}
+ {errors.name &&

{errors.name}

}
+ {errors.email &&

{errors.email}

}
+ {errors.subject &&

{errors.subject}

}