Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/menathndgd/caresync
CareSync is a modern Patient Management System built with React, Next.js, TailwindCSS, shadcn UI, Appwrite, Sentry, and Twilio. It streamlines patient care by managing appointments, records, and communication, offering real-time notifications and secure data handling.
https://github.com/menathndgd/caresync
Last synced: about 1 month ago
JSON representation
CareSync is a modern Patient Management System built with React, Next.js, TailwindCSS, shadcn UI, Appwrite, Sentry, and Twilio. It streamlines patient care by managing appointments, records, and communication, offering real-time notifications and secure data handling.
- Host: GitHub
- URL: https://github.com/menathndgd/caresync
- Owner: MenathNDGD
- Created: 2024-09-12T17:48:30.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2024-09-17T09:44:17.000Z (4 months ago)
- Last Synced: 2024-09-17T17:38:43.094Z (4 months ago)
- Language: TypeScript
- Size: 4.7 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
A HealthCare Management System
CareSync is a modern Patient Management System built with React, Next.js, TailwindCSS, shadcn UI, Appwrite, Sentry, and Twilio. It streamlines patient care by managing appointments, records, and communication, offering real-time notifications and secure data handling.
## π Table of Contents
1. π€ [Introduction](#introduction)
2. βοΈ [Tech Stack](#tech-stack)
3. π [Features](#features)
4. π€Έ [Quick Start](#quick-start)
5. πΈοΈ [Snippets (Code to Copy)](#snippets)
6. π [Assets](#links)
7. π [More Features Coming Soon](#more)CareSync is a modern health management platform designed to connect patients and healthcare providers through a seamless, user-friendly interface. The platform enables users to schedule appointments, access medical records, and manage their healthcare needs from one convenient location. With features like real-time notifications, telemedicine, and secure patient data handling, CareSync ensures that managing your healthcare is both efficient and secure.
Our project leverages a modern and robust tech stack to deliver a seamless experience:
- **Next.js**: A powerful React framework for server-side rendering and static site generation.
- **Appwrite**: An open-source backend server to manage database, authentication, and more.
- **TypeScript**: Adds type safety and clarity to our JavaScript code.
- **TailwindCSS**: A utility-first CSS framework for fast and responsive design.
- **ShadCN**: A tool for creating accessible and stylish UI components.
- **Twilio**: A cloud communications platform for SMS, voice, and video integration.Explore how these technologies come together to power our project!
- π― **Register as a Patient**: Easy sign-up to create personalized patient profiles.
- π― **Book Appointments**: Effortlessly schedule multiple appointments with doctors.
- π― **Admin Appointment Management**: Admins can view, manage, and handle all appointments.
- π― **Confirm/Schedule Appointments**: Admins ensure smooth scheduling and confirmation.
- π― **Cancel Appointments**: Admins can quickly cancel any appointment.
- π― **Appointment SMS Notifications**: Patients receive instant SMS confirmations upon appointment scheduling.
- π― **Responsive Design**: Seamless experience across all devices and screen sizes.
- π― **Secure File Uploads**: Upload files with confidence using Appwrite Storage.
- π― **Performance Tracking**: Monitor and optimize the appβs performance with Sentry.
and many more, including code architecture and reusability.
Follow these steps to set up the project locally on your machine.
**Prerequisites**
Make sure you have the following installed on your machine:
- [Git](https://git-scm.com/)
- [Node.js](https://nodejs.org/en)
- [NPM](https://www.npmjs.com/) (Node Package Manager)**Cloning the Repository**
```bash
git clone https://github.com/MenathNDGD/CareSync.git
cd CareSync
```**Installation**
Install the project dependencies using npm:
```bash
npm install
```**Set Up Environment Variables**
Create a new file named `.env.local` in the root of your project and add the following content:
```env
#APPWRITE
NEXT_PUBLIC_ENDPOINT=https://cloud.appwrite.io/v1
PROJECT_ID=
API_KEY=
DATABASE_ID=
PATIENT_COLLECTION_ID=
APPOINTMENT_COLLECTION_ID=
NEXT_PUBLIC_BUCKET_ID=NEXT_PUBLIC_ADMIN_PASSKEY=123456
```Replace the placeholder values with your actual Appwrite credentials. You can obtain these credentials by signing up on the [Appwrite website](https://appwrite.io/).
**Running the Project**
```bash
npm run dev
```Open [http://localhost:3000](http://localhost:3000) in your browser to view the project.
tailwind.config.ts
```typescript
import type { Config } from "tailwindcss";const { fontFamily } = require("tailwindcss/defaultTheme");
const config = {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
"./src/**/*.{ts,tsx}",
],
prefix: "",
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
green: {
500: "#24AE7C",
600: "#0D2A1F",
},
blue: {
500: "#79B5EC",
600: "#152432",
},
red: {
500: "#F37877",
600: "#3E1716",
700: "#F24E43",
},
light: {
200: "#E8E9E9",
},
dark: {
200: "#0D0F10",
300: "#131619",
400: "#1A1D21",
500: "#363A3D",
600: "#76828D",
700: "#ABB8C4",
},
},
fontFamily: {
sans: ["var(--font-sans)", ...fontFamily.sans],
},
backgroundImage: {
appointments: "url('/assets/images/appointments-bg.png')",
pending: "url('/assets/images/pending-bg.png')",
cancelled: "url('/assets/images/cancelled-bg.png')",
},
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: "0" },
},
"caret-blink": {
"0%,70%,100%": { opacity: "1" },
"20%,50%": { opacity: "0" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
"caret-blink": "caret-blink 1.25s ease-out infinite",
},
},
},
plugins: [require("tailwindcss-animate")],
} satisfies Config;export default config;
```
app/globals.css
```css
@tailwind base;
@tailwind components;
@tailwind utilities;/* ========================================== TAILWIND STYLES */
@layer base {
/* Remove scrollbar */
.remove-scrollbar::-webkit-scrollbar {
width: 0px;
height: 0px;
border-radius: 0px;
}.remove-scrollbar::-webkit-scrollbar-track {
background: transparent;
}.remove-scrollbar::-webkit-scrollbar-thumb {
background: transparent;
border-radius: 0px;
}.remove-scrollbar::-webkit-scrollbar-thumb:hover {
/* background: #1e2238; */
background: transparent;
}
}@layer utilities {
/* ===== UTILITIES */
.sidebar {
@apply remove-scrollbar w-full max-w-72 flex-col overflow-auto bg-black-800 px-7 py-10;
}.left-sidebar {
@apply hidden lg:flex;
}.right-sidebar {
@apply hidden xl:flex;
}.clip-text {
@apply bg-clip-text text-transparent;
}.bg-image {
@apply bg-black-900 bg-light-rays bg-cover bg-no-repeat;
}.header {
@apply text-32-bold md:text-36-bold;
}.sub-header {
@apply text-18-bold md:text-24-bold;
}.container {
@apply relative flex-1 overflow-y-auto px-[5%];
}.sub-container {
@apply mx-auto flex size-full flex-col py-10;
}.side-img {
@apply hidden h-full object-cover md:block;
}.copyright {
@apply text-14-regular justify-items-end text-center text-dark-600 xl:text-left;
}/* ==== SUCCESS */
.success-img {
@apply m-auto flex flex-1 flex-col items-center justify-between gap-10 py-10;
}.request-details {
@apply flex w-full flex-col items-center gap-8 border-y-2 border-dark-400 py-8 md:w-fit md:flex-row;
}/* ===== ADMIN */
.admin-header {
@apply sticky top-3 z-20 mx-3 flex items-center justify-between rounded-2xl bg-dark-200 px-[5%] py-5 shadow-lg xl:px-12;
}.admin-main {
@apply flex flex-col items-center space-y-6 px-[5%] pb-12 xl:space-y-12 xl:px-12;
}.admin-stat {
@apply flex w-full flex-col justify-between gap-5 sm:flex-row xl:gap-10;
}/* ==== FORM */
.radio-group {
@apply flex h-full flex-1 items-center gap-2 rounded-md border border-dashed border-dark-500 bg-dark-400 p-3;
}.checkbox-label {
@apply cursor-pointer text-sm font-medium text-dark-700 peer-disabled:cursor-not-allowed peer-disabled:opacity-70 md:leading-none;
}/* ==== File Upload */
.file-upload {
@apply text-12-regular flex cursor-pointer flex-col items-center justify-center gap-3 rounded-md border border-dashed border-dark-500 bg-dark-400 p-5;
}.file-upload_label {
@apply flex flex-col justify-center gap-2 text-center text-dark-600;
}/* ==== Stat Card */
.stat-card {
@apply flex flex-1 flex-col gap-6 rounded-2xl bg-cover p-6 shadow-lg;
}/* ==== Status Badge */
.status-badge {
@apply flex w-fit items-center gap-2 rounded-full px-4 py-2;
}/* Data Table */
.data-table {
@apply z-10 w-full overflow-hidden rounded-lg border border-dark-400 shadow-lg;
}.table-actions {
@apply flex w-full items-center justify-between space-x-2 p-4;
}/* ===== ALIGNMENTS */
.flex-center {
@apply flex items-center justify-center;
}.flex-between {
@apply flex items-center justify-between;
}/* ===== TYPOGRAPHY */
.text-36-bold {
@apply text-[36px] leading-[40px] font-bold;
}.text-24-bold {
@apply text-[24px] leading-[28px] font-bold;
}.text-32-bold {
@apply text-[32px] leading-[36px] font-bold;
}.text-18-bold {
@apply text-[18px] leading-[24px] font-bold;
}.text-16-semibold {
@apply text-[16px] leading-[20px] font-semibold;
}.text-16-regular {
@apply text-[16px] leading-[20px] font-normal;
}.text-14-medium {
@apply text-[14px] leading-[18px] font-medium;
}.text-14-regular {
@apply text-[14px] leading-[18px] font-normal;
}.text-12-regular {
@apply text-[12px] leading-[16px] font-normal;
}.text-12-semibold {
@apply text-[12px] leading-[16px] font-semibold;
}/* ===== SHADCN OVERRIDES */
.shad-primary-btn {
@apply bg-green-500 text-white !important;
}.shad-danger-btn {
@apply bg-red-700 text-white !important;
}.shad-gray-btn {
@apply border border-dark-500 cursor-pointer bg-dark-400 text-white !important;
}.shad-input-label {
@apply text-14-medium text-dark-700 !important;
}.shad-input {
@apply bg-dark-400 placeholder:text-dark-600 border-dark-500 h-11 focus-visible:ring-0 focus-visible:ring-offset-0 !important;
}.shad-input-icon {
@apply bg-dark-400 placeholder:text-dark-600 border-dark-500 h-11 focus-visible:ring-0 focus-visible:ring-offset-0 !important;
}.shad-textArea {
@apply bg-dark-400 placeholder:text-dark-600 border-dark-500 focus-visible:ring-0 focus-visible:ring-offset-0 !important;
}.shad-combobox-item {
@apply data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 !important;
}.shad-combobox-trigger {
@apply h-11 !important;
}.shad-select-trigger {
@apply bg-dark-400 placeholder:text-dark-600 border-dark-500 h-11 focus:ring-0 focus:ring-offset-0 !important;
}.shad-select-content {
@apply bg-dark-400 border-dark-500 !important;
}.shad-dialog {
@apply bg-dark-400 border-dark-500 !important;
}.shad-dialog button {
@apply focus:ring-0 focus:ring-offset-0 focus-visible:border-none focus-visible:outline-none focus-visible:ring-transparent focus-visible:ring-offset-0 !important;
}.shad-error {
@apply text-red-400 !important;
}.shad-table {
@apply rounded-lg overflow-hidden !important;
}.shad-table-row-header {
@apply border-b border-dark-400 text-light-200 hover:bg-transparent !important;
}.shad-table-row {
@apply border-b border-dark-400 text-light-200 !important;
}.shad-otp {
@apply w-full flex justify-between !important;
}.shad-otp-slot {
@apply text-36-bold justify-center flex border border-dark-500 rounded-lg size-16 gap-4 !important;
}.shad-alert-dialog {
@apply space-y-5 bg-dark-400 border-dark-500 outline-none !important;
}.shad-sheet-content button {
@apply top-2 focus:ring-0 focus:ring-offset-0 focus-visible:border-none focus-visible:outline-none focus-visible:ring-transparent focus-visible:ring-offset-0 !important;
}/* ===== REACT PHONE NUMBER INPUT OVERRIDES */
.input-phone {
@apply mt-2 h-11 rounded-md px-3 text-sm border bg-dark-400 placeholder:text-dark-600 border-dark-500 !important;
}/* ===== REACT DATE PICKER OVERRIDES */
.date-picker {
@apply overflow-hidden border-transparent w-full placeholder:text-dark-600 h-11 text-14-medium rounded-md px-3 outline-none !important;
}
}/* ===== REACT-DATEPICKER OVERRIDES */
.react-datepicker-wrapper.date-picker {
display: flex;
align-items: center;
}.react-datepicker,
.react-datepicker__time,
.react-datepicker__header,
.react-datepicker__current-month,
.react-datepicker__day-name,
.react-datepicker__day,
.react-datepicker-time__header {
background-color: #1a1d21 !important;
border-color: #363a3d !important;
color: #abb8c4 !important;
}.react-datepicker__current-month,
.react-datepicker__day-name,
.react-datepicker-time__header {
color: #ffffff !important;
}.react-datepicker__triangle {
fill: #1a1d21 !important;
color: #1a1d21 !important;
stroke: #1a1d21 !important;
}.react-datepicker__time-list-item:hover {
background-color: #363a3d !important;
}.react-datepicker__input-container input {
background-color: #1a1d21 !important;
width: 100%;
outline: none;
}.react-datepicker__day--selected {
background-color: #24ae7c !important;
color: #ffffff !important;
border-radius: 4px;
}.react-datepicker__time-list-item--selected {
background-color: #24ae7c !important;
}.react-datepicker__time-container {
border-left: 1px solid #363a3d !important;
}.react-datepicker__time-list-item {
display: flex !important;
align-items: center !important;
}/* ===== REACT PHONE NUMBER INPUT OVERRIDES */
.PhoneInputInput {
outline: none;
margin-left: 4px;
background: #1a1d21;
font-size: 14px;
font-weight: 500;
}.PhoneInputInput::placeholder {
color: #1a1d21;
}
```
types/index.d.ts
```typescript
/* eslint-disable no-unused-vars */declare type SearchParamProps = {
params: { [key: string]: string };
searchParams: { [key: string]: string | string[] | undefined };
};declare type Gender = "Male" | "Female" | "Other";
declare type Status = "pending" | "scheduled" | "cancelled";declare interface CreateUserParams {
name: string;
email: string;
phone: string;
}
declare interface User extends CreateUserParams {
$id: string;
}declare interface RegisterUserParams extends CreateUserParams {
userId: string;
birthDate: Date;
gender: Gender;
address: string;
occupation: string;
emergencyContactName: string;
emergencyContactNumber: string;
primaryPhysician: string;
insuranceProvider: string;
insurancePolicyNumber: string;
allergies: string | undefined;
currentMedication: string | undefined;
familyMedicalHistory: string | undefined;
pastMedicalHistory: string | undefined;
identificationType: string | undefined;
identificationNumber: string | undefined;
identificationDocument: FormData | undefined;
privacyConsent: boolean;
}declare type CreateAppointmentParams = {
userId: string;
patient: string;
primaryPhysician: string;
reason: string;
schedule: Date;
status: Status;
note: string | undefined;
};declare type UpdateAppointmentParams = {
appointmentId: string;
userId: string;
appointment: Appointment;
type: string;
};
```
types/appwrite.types.ts
```typescript
import { Models } from "node-appwrite";export interface Patient extends Models.Document {
userId: string;
name: string;
email: string;
phone: string;
birthDate: Date;
gender: Gender;
address: string;
occupation: string;
emergencyContactName: string;
emergencyContactNumber: string;
primaryPhysician: string;
insuranceProvider: string;
insurancePolicyNumber: string;
allergies: string | undefined;
currentMedication: string | undefined;
familyMedicalHistory: string | undefined;
pastMedicalHistory: string | undefined;
identificationType: string | undefined;
identificationNumber: string | undefined;
identificationDocument: FormData | undefined;
privacyConsent: boolean;
}export interface Appointment extends Models.Document {
patient: Patient;
schedule: Date;
status: Status;
primaryPhysician: string;
reason: string;
note: string;
userId: string;
cancellationReason: string | null;
}
```
lib/utils.ts
```typescript
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}export const parseStringify = (value: any) => JSON.parse(JSON.stringify(value));
export const convertFileToUrl = (file: File) => URL.createObjectURL(file);
// FORMAT DATE TIME
export const formatDateTime = (dateString: Date | string) => {
const dateTimeOptions: Intl.DateTimeFormatOptions = {
// weekday: "short", // abbreviated weekday name (e.g., 'Mon')
month: "short", // abbreviated month name (e.g., 'Oct')
day: "numeric", // numeric day of the month (e.g., '25')
year: "numeric", // numeric year (e.g., '2023')
hour: "numeric", // numeric hour (e.g., '8')
minute: "numeric", // numeric minute (e.g., '30')
hour12: true, // use 12-hour clock (true) or 24-hour clock (false)
};const dateDayOptions: Intl.DateTimeFormatOptions = {
weekday: "short", // abbreviated weekday name (e.g., 'Mon')
year: "numeric", // numeric year (e.g., '2023')
month: "2-digit", // abbreviated month name (e.g., 'Oct')
day: "2-digit", // numeric day of the month (e.g., '25')
};const dateOptions: Intl.DateTimeFormatOptions = {
month: "short", // abbreviated month name (e.g., 'Oct')
year: "numeric", // numeric year (e.g., '2023')
day: "numeric", // numeric day of the month (e.g., '25')
};const timeOptions: Intl.DateTimeFormatOptions = {
hour: "numeric", // numeric hour (e.g., '8')
minute: "numeric", // numeric minute (e.g., '30')
hour12: true, // use 12-hour clock (true) or 24-hour clock (false)
};const formattedDateTime: string = new Date(dateString).toLocaleString(
"en-US",
dateTimeOptions
);const formattedDateDay: string = new Date(dateString).toLocaleString(
"en-US",
dateDayOptions
);const formattedDate: string = new Date(dateString).toLocaleString(
"en-US",
dateOptions
);const formattedTime: string = new Date(dateString).toLocaleString(
"en-US",
timeOptions
);return {
dateTime: formattedDateTime,
dateDay: formattedDateDay,
dateOnly: formattedDate,
timeOnly: formattedTime,
};
};export function encryptKey(passkey: string) {
return btoa(passkey);
}export function decryptKey(passkey: string) {
return atob(passkey);
}
```
lib/validation.ts
```typescript
import { z } from "zod";export const UserFormValidation = z.object({
name: z
.string()
.min(2, "Name must be at least 2 characters")
.max(50, "Name must be at most 50 characters"),
email: z.string().email("Invalid email address"),
phone: z
.string()
.refine((phone) => /^\+\d{10,15}$/.test(phone), "Invalid phone number"),
});export const PatientFormValidation = z.object({
name: z
.string()
.min(2, "Name must be at least 2 characters")
.max(50, "Name must be at most 50 characters"),
email: z.string().email("Invalid email address"),
phone: z
.string()
.refine((phone) => /^\+\d{10,15}$/.test(phone), "Invalid phone number"),
birthDate: z.coerce.date(),
gender: z.enum(["Male", "Female", "Other"]),
address: z
.string()
.min(5, "Address must be at least 5 characters")
.max(500, "Address must be at most 500 characters"),
occupation: z
.string()
.min(2, "Occupation must be at least 2 characters")
.max(500, "Occupation must be at most 500 characters"),
emergencyContactName: z
.string()
.min(2, "Contact name must be at least 2 characters")
.max(50, "Contact name must be at most 50 characters"),
emergencyContactNumber: z
.string()
.refine(
(emergencyContactNumber) => /^\+\d{10,15}$/.test(emergencyContactNumber),
"Invalid phone number"
),
primaryPhysician: z.string().min(2, "Select at least one doctor"),
insuranceProvider: z
.string()
.min(2, "Insurance name must be at least 2 characters")
.max(50, "Insurance name must be at most 50 characters"),
insurancePolicyNumber: z
.string()
.min(2, "Policy number must be at least 2 characters")
.max(50, "Policy number must be at most 50 characters"),
allergies: z.string().optional(),
currentMedication: z.string().optional(),
familyMedicalHistory: z.string().optional(),
pastMedicalHistory: z.string().optional(),
identificationType: z.string().optional(),
identificationNumber: z.string().optional(),
identificationDocument: z.custom().optional(),
treatmentConsent: z
.boolean()
.default(false)
.refine((value) => value === true, {
message: "You must consent to treatment in order to proceed",
}),
disclosureConsent: z
.boolean()
.default(false)
.refine((value) => value === true, {
message: "You must consent to disclosure in order to proceed",
}),
privacyConsent: z
.boolean()
.default(false)
.refine((value) => value === true, {
message: "You must consent to privacy in order to proceed",
}),
});export const CreateAppointmentSchema = z.object({
primaryPhysician: z.string().min(2, "Select at least one doctor"),
schedule: z.coerce.date(),
reason: z
.string()
.min(2, "Reason must be at least 2 characters")
.max(500, "Reason must be at most 500 characters"),
note: z.string().optional(),
cancellationReason: z.string().optional(),
});export const ScheduleAppointmentSchema = z.object({
primaryPhysician: z.string().min(2, "Select at least one doctor"),
schedule: z.coerce.date(),
reason: z.string().optional(),
note: z.string().optional(),
cancellationReason: z.string().optional(),
});export const CancelAppointmentSchema = z.object({
primaryPhysician: z.string().min(2, "Select at least one doctor"),
schedule: z.coerce.date(),
reason: z.string().optional(),
note: z.string().optional(),
cancellationReason: z
.string()
.min(2, "Reason must be at least 2 characters")
.max(500, "Reason must be at most 500 characters"),
});export function getAppointmentSchema(type: string) {
switch (type) {
case "create":
return CreateAppointmentSchema;
case "cancel":
return CancelAppointmentSchema;
default:
return ScheduleAppointmentSchema;
}
}
```
constants/index.ts
```typescript
export const GenderOptions = ["Male", "Female", "Other"];export const PatientFormDefaultValues = {
firstName: "",
lastName: "",
email: "",
phone: "",
birthDate: new Date(Date.now()),
gender: "Male" as Gender,
address: "",
occupation: "",
emergencyContactName: "",
emergencyContactNumber: "",
primaryPhysician: "",
insuranceProvider: "",
insurancePolicyNumber: "",
allergies: "",
currentMedication: "",
familyMedicalHistory: "",
pastMedicalHistory: "",
identificationType: "Birth Certificate",
identificationNumber: "",
identificationDocument: [],
treatmentConsent: false,
disclosureConsent: false,
privacyConsent: false,
};export const IdentificationTypes = [
"Birth Certificate",
"Driver's License",
"Medical Insurance Card/Policy",
"Military ID Card",
"National Identity Card",
"Passport",
"Resident Alien Card (Green Card)",
"Social Security Card",
"State ID Card",
"Student ID Card",
"Voter ID Card",
];export const Doctors = [
{
image: "/assets/images/dr-green.png",
name: "John Green",
},
{
image: "/assets/images/dr-cameron.png",
name: "Leila Cameron",
},
{
image: "/assets/images/dr-livingston.png",
name: "David Livingston",
},
{
image: "/assets/images/dr-peter.png",
name: "Evan Peter",
},
{
image: "/assets/images/dr-powell.png",
name: "Jane Powell",
},
{
image: "/assets/images/dr-remirez.png",
name: "Alex Ramirez",
},
{
image: "/assets/images/dr-lee.png",
name: "Jasmine Lee",
},
{
image: "/assets/images/dr-cruz.png",
name: "Alyana Cruz",
},
{
image: "/assets/images/dr-sharma.png",
name: "Hardik Sharma",
},
];export const StatusIcon = {
scheduled: "/assets/icons/check.svg",
pending: "/assets/icons/pending.svg",
cancelled: "/assets/icons/cancelled.svg",
};
```## π Assets
Access all the public assets used in the project, including images, icons, and other media files, from our shared drive. Feel free to download and explore them:
[Click here to view and download assets](https://drive.google.com/file/d/1yGvWFeSaH1_-aiQ1gejT23lqz5979RKB/view?usp=sharing)
We've updated our logo for a more modern and refreshing look! The new **CareSync** logo represents our commitment to delivering cutting-edge healthcare management. Here's how to update it in your project:
Replace **logo-full.svg** with **logo-full.png**:
1. Navigate to the `/public/assets/icons/` folder.
2. Delete `logo-full.svg`.
3. Add the new **CareSync** logo as `logo-full.png`.This new logo aligns perfectly with our mission of simplifying healthcare management. Check it out and let us know what you think!
## π More Features Coming Soon
Weβre continually enhancing CareSync to provide the best experience possible. Hereβs what you can expect in future updates:
- π **Telemedicine**: Virtual doctor consultations within the app.
- π **In-depth Analytics**: Comprehensive reports on patient records and appointment trends.
- π **Advanced Security**: Two-factor authentication for enhanced security.
- π **Health Reminders**: Personalized notifications for medication, appointments, and more.
- π **Integration with Wearables**: Sync health data from smartwatches and fitness trackers.Stay tuned for more exciting features and improvements! π
#