From 72e8422d2dfaf26e2c351f5daade27b962aa1462 Mon Sep 17 00:00:00 2001 From: Mauricio Sevilla Date: Mon, 9 Mar 2026 17:31:06 -0600 Subject: [PATCH 1/6] feat: add historial y agenda endpoints con seeders --- app/api/agenda/[matricula_doctor]/route.ts | 35 +++++++++++++ app/api/historial/[matricula]/route.ts | 29 +++++++++++ bun.lock | 1 + lib/seeders/agenda.ts | 43 ++++++++++++++++ lib/seeders/historial.ts | 59 ++++++++++++++++++++++ 5 files changed, 167 insertions(+) create mode 100644 app/api/agenda/[matricula_doctor]/route.ts create mode 100644 app/api/historial/[matricula]/route.ts create mode 100644 lib/seeders/agenda.ts create mode 100644 lib/seeders/historial.ts diff --git a/app/api/agenda/[matricula_doctor]/route.ts b/app/api/agenda/[matricula_doctor]/route.ts new file mode 100644 index 0000000..42ed5da --- /dev/null +++ b/app/api/agenda/[matricula_doctor]/route.ts @@ -0,0 +1,35 @@ +import { NextRequest, NextResponse } from "next/server"; +import { agendaSeed } from "@/lib/seeders/agenda"; + +export async function GET( + request: NextRequest, + { params }: { params: Promise<{ matricula_doctor: string }> } +) { + const { matricula_doctor } = await params; + const fecha = request.nextUrl.searchParams.get("fecha"); + + let citas = agendaSeed.filter( + (c) => c.matricula_doctor === matricula_doctor + ); + + if (fecha) { + citas = citas.filter((c) => c.fecha === fecha); + } + + if (citas.length === 0) { + return NextResponse.json( + { error: `No se encontraron citas para el doctor ${matricula_doctor}` }, + { status: 404 } + ); + } + + return NextResponse.json( + { + matricula_doctor, + fecha: fecha ?? "todas", + total: citas.length, + agenda: citas, + }, + { status: 200 } + ); +} \ No newline at end of file diff --git a/app/api/historial/[matricula]/route.ts b/app/api/historial/[matricula]/route.ts new file mode 100644 index 0000000..9a2c957 --- /dev/null +++ b/app/api/historial/[matricula]/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; +import { historialSeed } from "@/lib/seeders/historial"; + +export async function GET( + request: NextRequest, + { params }: { params: Promise<{ matricula: string }> } +) { + const { matricula } = await params; + + const consultas = historialSeed.filter( + (c) => c.matricula_paciente === matricula + ); + + if (consultas.length === 0) { + return NextResponse.json( + { error: `No se encontró historial para la matrícula ${matricula}` }, + { status: 404 } + ); + } + + return NextResponse.json( + { + matricula, + total: consultas.length, + historial: consultas, + }, + { status: 200 } + ); +} \ No newline at end of file diff --git a/bun.lock b/bun.lock index da2d77b..d912294 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "medical-app", diff --git a/lib/seeders/agenda.ts b/lib/seeders/agenda.ts new file mode 100644 index 0000000..d8ab2d7 --- /dev/null +++ b/lib/seeders/agenda.ts @@ -0,0 +1,43 @@ +export type Cita = { + id: string; + matricula_doctor: string; + matricula_paciente: string; + nombre_paciente: string; + fecha: string; + estatus: "pendiente" | "completada" | "cancelada"; +}; + +export const agendaSeed: Cita[] = [ + { + id: "a-001", + matricula_doctor: "DOC-001", + matricula_paciente: "PAC-001", + nombre_paciente: "Juan García", + fecha: "2026-03-09", + estatus: "pendiente", + }, + { + id: "a-002", + matricula_doctor: "DOC-001", + matricula_paciente: "PAC-002", + nombre_paciente: "María López", + fecha: "2026-03-09", + estatus: "completada", + }, + { + id: "a-003", + matricula_doctor: "DOC-001", + matricula_paciente: "PAC-003", + nombre_paciente: "Carlos Ruiz", + fecha: "2026-03-09", + estatus: "cancelada", + }, + { + id: "a-004", + matricula_doctor: "DOC-002", + matricula_paciente: "PAC-004", + nombre_paciente: "Ana Torres", + fecha: "2026-03-09", + estatus: "pendiente", + }, +]; \ No newline at end of file diff --git a/lib/seeders/historial.ts b/lib/seeders/historial.ts new file mode 100644 index 0000000..bee1101 --- /dev/null +++ b/lib/seeders/historial.ts @@ -0,0 +1,59 @@ +export type Consulta = { + id: string; + matricula_paciente: string; + fecha: string; + diagnostico: string; + tratamiento: string; + medico_responsable: string; +}; + +export const historialSeed: Consulta[] = [ + { + id: "c-001", + matricula_paciente: "PAC-001", + fecha: "2025-01-15", + diagnostico: "Hipertensión arterial leve", + tratamiento: "Losartán 50mg cada 24 horas", + medico_responsable: "Dr. Carlos Méndez", + }, + { + id: "c-002", + matricula_paciente: "PAC-001", + fecha: "2025-03-02", + diagnostico: "Infección respiratoria aguda", + tratamiento: "Amoxicilina 500mg cada 8 horas por 7 días", + medico_responsable: "Dra. Laura Ríos", + }, + { + id: "c-003", + matricula_paciente: "PAC-001", + fecha: "2025-06-20", + diagnostico: "Gastritis crónica", + tratamiento: "Omeprazol 20mg en ayunas por 30 días", + medico_responsable: "Dr. Carlos Méndez", + }, + { + id: "c-004", + matricula_paciente: "PAC-002", + fecha: "2025-02-10", + diagnostico: "Diabetes tipo 2", + tratamiento: "Metformina 850mg con cada comida", + medico_responsable: "Dra. Laura Ríos", + }, + { + id: "c-005", + matricula_paciente: "PAC-002", + fecha: "2025-04-18", + diagnostico: "Control glucémico", + tratamiento: "Ajuste de dosis: Metformina 1000mg", + medico_responsable: "Dra. Laura Ríos", + }, + { + id: "c-006", + matricula_paciente: "PAC-002", + fecha: "2025-07-05", + diagnostico: "Neuropatía diabética leve", + tratamiento: "Vitamina B12 + control mensual", + medico_responsable: "Dr. Carlos Méndez", + }, +]; \ No newline at end of file From b8e2b7e4500151b2761f65750b084da9dbbcebf3 Mon Sep 17 00:00:00 2001 From: CodingGaby Date: Mon, 9 Mar 2026 22:03:34 -0600 Subject: [PATCH 2/6] fix(app): Config update Config updated in order for the project to be more scalable --- app/types/InputTypes.ts | 17 +++++++++++++++++ next.config.ts | 9 ++++++++- tsconfig.json | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 app/types/InputTypes.ts diff --git a/app/types/InputTypes.ts b/app/types/InputTypes.ts new file mode 100644 index 0000000..ce94f80 --- /dev/null +++ b/app/types/InputTypes.ts @@ -0,0 +1,17 @@ +export type InputType = "checkbox" | "color" | "date" | "datetime-local" | "email" | "file" | "hidden" | "month" | "number" | "password" | "search" | "tel" | "text" | "time" | "url" | "week"; + +export type InputField = { + title: string; + type: InputType; + isRequired: boolean; + placeholder?: string; +} + +export type InputFieldArr = { + name: string; + label: string; + type: InputType; + isRequired: boolean; + placeholder?: string; + value?: string | number; +}; \ No newline at end of file diff --git a/next.config.ts b/next.config.ts index e9ffa30..aeb9320 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,14 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: 'images.pexels.com', + }, + ], + }, }; export default nextConfig; diff --git a/tsconfig.json b/tsconfig.json index 8a00584..fb033e7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,7 +20,7 @@ ], "paths": { "@/*": ["./*"], - "@/types/*": ["./app/types/*"], + "@/Types/*": ["./app/types/*"], "@/Components/*": ["./app/components/*"] } }, From ccc473e80235d043b76867f8de4944a3afa146ea Mon Sep 17 00:00:00 2001 From: CodingGaby Date: Mon, 9 Mar 2026 22:07:02 -0600 Subject: [PATCH 3/6] =?UTF-8?q?feat(app):=20UI=20improvement=20and=20Compo?= =?UTF-8?q?nents=20=F0=9F=8E=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/components/Buttons/SubmitBtn.tsx | 13 ++++++++ app/components/Forms/Form.tsx | 13 ++++++++ app/components/Forms/FormInput.tsx | 48 ++++++++++++++++++++++++++++ app/layout.tsx | 11 +++++-- 4 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 app/components/Buttons/SubmitBtn.tsx create mode 100644 app/components/Forms/Form.tsx create mode 100644 app/components/Forms/FormInput.tsx diff --git a/app/components/Buttons/SubmitBtn.tsx b/app/components/Buttons/SubmitBtn.tsx new file mode 100644 index 0000000..c947037 --- /dev/null +++ b/app/components/Buttons/SubmitBtn.tsx @@ -0,0 +1,13 @@ +interface Props { + children: React.ReactNode; +} +export default function SubmitBtn({ children }: Props) { + return ( + + ); +} diff --git a/app/components/Forms/Form.tsx b/app/components/Forms/Form.tsx new file mode 100644 index 0000000..e8998dd --- /dev/null +++ b/app/components/Forms/Form.tsx @@ -0,0 +1,13 @@ +export default function Form({ title, children }: { title: string; children: React.ReactNode }) { + return ( +
+

+ {title} +

+ {children} +
+ ); +} diff --git a/app/components/Forms/FormInput.tsx b/app/components/Forms/FormInput.tsx new file mode 100644 index 0000000..63ff9f5 --- /dev/null +++ b/app/components/Forms/FormInput.tsx @@ -0,0 +1,48 @@ +import { InputType } from "@/Types/InputTypes"; + +interface Props { + name: string; + title?: string; + type: InputType; + isRequired?: boolean; + placeholder?: string; + value?: string | number; + isDisabled?: boolean; + children?: React.ReactNode; +} +export default function FormInput({ + name, + title, + type, + isRequired, + placeholder, + value, + isDisabled, + children, +}: Props) { + return ( +
+ + +
+ ); +} diff --git a/app/layout.tsx b/app/layout.tsx index f7fa87e..d57ae50 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -24,10 +24,17 @@ export default function RootLayout({ }>) { return ( + + + + + - {children} +
+ {children} +
); From 1034cc48ef3e24ab8046031374263c10bed08613 Mon Sep 17 00:00:00 2001 From: CodingGaby Date: Tue, 10 Mar 2026 09:55:21 -0600 Subject: [PATCH 4/6] =?UTF-8?q?build(app):=20Turso=20added=20=F0=9F=9B=A0?= =?UTF-8?q?=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/turso.ts | 6 +++++ bun.lock | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-- package.json | 1 + 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 app/turso.ts diff --git a/app/turso.ts b/app/turso.ts new file mode 100644 index 0000000..79560a5 --- /dev/null +++ b/app/turso.ts @@ -0,0 +1,6 @@ +import { createClient } from "@libsql/client"; + +export const turso = createClient({ + url: process.env.TURSO_DATABASE_URL, + authToken: process.env.TURSO_AUTH_TOKEN, +}); \ No newline at end of file diff --git a/bun.lock b/bun.lock index d912294..3782fb2 100644 --- a/bun.lock +++ b/bun.lock @@ -1,10 +1,10 @@ { "lockfileVersion": 1, - "configVersion": 0, "workspaces": { "": { "name": "medical-app", "dependencies": { + "@libsql/client": "^0.17.0", "lucide-react": "^0.575.0", "next": "16.1.6", "react": "19.2.3", @@ -153,8 +153,36 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + "@libsql/client": ["@libsql/client@0.17.0", "", { "dependencies": { "@libsql/core": "^0.17.0", "@libsql/hrana-client": "^0.9.0", "js-base64": "^3.7.5", "libsql": "^0.5.22", "promise-limit": "^2.7.0" } }, "sha512-TLjSU9Otdpq0SpKHl1tD1Nc9MKhrsZbCFGot3EbCxRa8m1E5R1mMwoOjKMMM31IyF7fr+hPNHLpYfwbMKNusmg=="], + + "@libsql/core": ["@libsql/core@0.17.0", "", { "dependencies": { "js-base64": "^3.7.5" } }, "sha512-hnZRnJHiS+nrhHKLGYPoJbc78FE903MSDrFJTbftxo+e52X+E0Y0fHOCVYsKWcg6XgB7BbJYUrz/xEkVTSaipw=="], + + "@libsql/darwin-arm64": ["@libsql/darwin-arm64@0.5.22", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4B8ZlX3nIDPndfct7GNe0nI3Yw6ibocEicWdC4fvQbSs/jdq/RC2oCsoJxJ4NzXkvktX70C1J4FcmmoBy069UA=="], + + "@libsql/darwin-x64": ["@libsql/darwin-x64@0.5.22", "", { "os": "darwin", "cpu": "x64" }, "sha512-ny2HYWt6lFSIdNFzUFIJ04uiW6finXfMNJ7wypkAD8Pqdm6nAByO+Fdqu8t7sD0sqJGeUCiOg480icjyQ2/8VA=="], + + "@libsql/hrana-client": ["@libsql/hrana-client@0.9.0", "", { "dependencies": { "@libsql/isomorphic-ws": "^0.1.5", "cross-fetch": "^4.0.0", "js-base64": "^3.7.5", "node-fetch": "^3.3.2" } }, "sha512-pxQ1986AuWfPX4oXzBvLwBnfgKDE5OMhAdR/5cZmRaB4Ygz5MecQybvwZupnRz341r2CtFmbk/BhSu7k2Lm+Jw=="], + + "@libsql/isomorphic-ws": ["@libsql/isomorphic-ws@0.1.5", "", { "dependencies": { "@types/ws": "^8.5.4", "ws": "^8.13.0" } }, "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg=="], + + "@libsql/linux-arm-gnueabihf": ["@libsql/linux-arm-gnueabihf@0.5.22", "", { "os": "linux", "cpu": "arm" }, "sha512-3Uo3SoDPJe/zBnyZKosziRGtszXaEtv57raWrZIahtQDsjxBVjuzYQinCm9LRCJCUT5t2r5Z5nLDPJi2CwZVoA=="], + + "@libsql/linux-arm-musleabihf": ["@libsql/linux-arm-musleabihf@0.5.22", "", { "os": "linux", "cpu": "arm" }, "sha512-LCsXh07jvSojTNJptT9CowOzwITznD+YFGGW+1XxUr7fS+7/ydUrpDfsMX7UqTqjm7xG17eq86VkWJgHJfvpNg=="], + + "@libsql/linux-arm64-gnu": ["@libsql/linux-arm64-gnu@0.5.22", "", { "os": "linux", "cpu": "arm64" }, "sha512-KSdnOMy88c9mpOFKUEzPskSaF3VLflfSUCBwas/pn1/sV3pEhtMF6H8VUCd2rsedwoukeeCSEONqX7LLnQwRMA=="], + + "@libsql/linux-arm64-musl": ["@libsql/linux-arm64-musl@0.5.22", "", { "os": "linux", "cpu": "arm64" }, "sha512-mCHSMAsDTLK5YH//lcV3eFEgiR23Ym0U9oEvgZA0667gqRZg/2px+7LshDvErEKv2XZ8ixzw3p1IrBzLQHGSsw=="], + + "@libsql/linux-x64-gnu": ["@libsql/linux-x64-gnu@0.5.22", "", { "os": "linux", "cpu": "x64" }, "sha512-kNBHaIkSg78Y4BqAdgjcR2mBilZXs4HYkAmi58J+4GRwDQZh5fIUWbnQvB9f95DkWUIGVeenqLRFY2pcTmlsew=="], + + "@libsql/linux-x64-musl": ["@libsql/linux-x64-musl@0.5.22", "", { "os": "linux", "cpu": "x64" }, "sha512-UZ4Xdxm4pu3pQXjvfJiyCzZop/9j/eA2JjmhMaAhe3EVLH2g11Fy4fwyUp9sT1QJYR1kpc2JLuybPM0kuXv/Tg=="], + + "@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.5.22", "", { "os": "win32", "cpu": "x64" }, "sha512-Fj0j8RnBpo43tVZUVoNK6BV/9AtDUM5S7DF3LB4qTYg1LMSZqi3yeCneUTLJD6XomQJlZzbI4mst89yspVSAnA=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="], + "@neon-rs/load": ["@neon-rs/load@0.0.4", "", {}, "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw=="], + "@next/env": ["@next/env@16.1.6", "", {}, "sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ=="], "@next/eslint-plugin-next": ["@next/eslint-plugin-next@16.1.6", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ=="], @@ -231,6 +259,8 @@ "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.56.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/type-utils": "8.56.1", "@typescript-eslint/utils": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.56.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A=="], "@typescript-eslint/parser": ["@typescript-eslint/parser@8.56.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", "@typescript-eslint/typescript-estree": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg=="], @@ -359,12 +389,16 @@ "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + "cross-fetch": ["cross-fetch@4.1.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw=="], + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], "damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="], + "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], + "data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="], "data-view-byte-length": ["data-view-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ=="], @@ -379,7 +413,7 @@ "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="], - "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="], "doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="], @@ -455,6 +489,8 @@ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], + "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], @@ -467,6 +503,8 @@ "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], + "formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="], + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], "function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="], @@ -581,6 +619,8 @@ "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + "js-base64": ["js-base64@3.7.8", "", {}, "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow=="], + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], @@ -605,6 +645,8 @@ "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + "libsql": ["libsql@0.5.22", "", { "dependencies": { "@neon-rs/load": "^0.0.4", "detect-libc": "2.0.2" }, "optionalDependencies": { "@libsql/darwin-arm64": "0.5.22", "@libsql/darwin-x64": "0.5.22", "@libsql/linux-arm-gnueabihf": "0.5.22", "@libsql/linux-arm-musleabihf": "0.5.22", "@libsql/linux-arm64-gnu": "0.5.22", "@libsql/linux-arm64-musl": "0.5.22", "@libsql/linux-x64-gnu": "0.5.22", "@libsql/linux-x64-musl": "0.5.22", "@libsql/win32-x64-msvc": "0.5.22" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "arm", "x64", "arm64", ] }, "sha512-NscWthMQt7fpU8lqd7LXMvT9pi+KhhmTHAJWUB/Lj6MWa0MKFv0F2V4C6WKKpjCVZl0VwcDz4nOI3CyaT1DDiA=="], + "lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="], "lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="], @@ -661,8 +703,12 @@ "next": ["next@16.1.6", "", { "dependencies": { "@next/env": "16.1.6", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.6", "@next/swc-darwin-x64": "16.1.6", "@next/swc-linux-arm64-gnu": "16.1.6", "@next/swc-linux-arm64-musl": "16.1.6", "@next/swc-linux-x64-gnu": "16.1.6", "@next/swc-linux-x64-musl": "16.1.6", "@next/swc-win32-arm64-msvc": "16.1.6", "@next/swc-win32-x64-msvc": "16.1.6", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw=="], + "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], + "node-exports-info": ["node-exports-info@1.6.0", "", { "dependencies": { "array.prototype.flatmap": "^1.3.3", "es-errors": "^1.3.0", "object.entries": "^1.1.9", "semver": "^6.3.1" } }, "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw=="], + "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], + "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="], "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], @@ -707,6 +753,8 @@ "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], + "promise-limit": ["promise-limit@2.7.0", "", {}, "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="], + "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], @@ -799,6 +847,8 @@ "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + "ts-api-utils": ["ts-api-utils@2.4.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA=="], "tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="], @@ -829,6 +879,12 @@ "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], + + "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], + + "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], "which-boxed-primitive": ["which-boxed-primitive@1.1.1", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="], @@ -841,6 +897,8 @@ "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], + "ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], + "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], @@ -875,6 +933,8 @@ "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + "cross-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], "eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], @@ -887,10 +947,14 @@ "is-bun-module/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + "lightningcss/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], + "sharp/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "sharp/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.3", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA=="], diff --git a/package.json b/package.json index 16c014f..6841871 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "eslint" }, "dependencies": { + "@libsql/client": "^0.17.0", "lucide-react": "^0.575.0", "next": "16.1.6", "react": "19.2.3", From ea6a6f7cc76723e4c2ae059fa5c880255d3e2dce Mon Sep 17 00:00:00 2001 From: CodingGaby Date: Tue, 10 Mar 2026 11:17:37 -0600 Subject: [PATCH 5/6] =?UTF-8?q?fix(app):=20Best=20client=20implementation?= =?UTF-8?q?=20=F0=9F=9B=A0=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added checks for url and token from turso --- app/turso.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/turso.ts b/app/turso.ts index 79560a5..f8cedbe 100644 --- a/app/turso.ts +++ b/app/turso.ts @@ -1,5 +1,13 @@ import { createClient } from "@libsql/client"; +if (!process.env.TURSO_DATABASE_URL) { + throw new Error("TURSO_DATABASE_URL no está definida"); +} + +if (!process.env.TURSO_AUTH_TOKEN) { + throw new Error("TURSO_AUTH_TOKEN no está definida"); +} + export const turso = createClient({ url: process.env.TURSO_DATABASE_URL, authToken: process.env.TURSO_AUTH_TOKEN, From 076c9c024f178f5fd0834fabc31defd8185089a3 Mon Sep 17 00:00:00 2001 From: CodingGaby Date: Wed, 11 Mar 2026 22:36:31 -0600 Subject: [PATCH 6/6] fix(app): Improved ui standardization --- app/components/Forms/FormInput.tsx | 10 ++++++++- app/components/UI/Counter.tsx | 15 +++++++++++++ app/components/UI/Icons/LoaderIcon.tsx | 7 ++++++ app/components/UI/StatusPill.tsx | 31 ++++++++++++++++++++++++++ app/components/UI/UserIcon.tsx | 9 ++++++++ app/types/AcceptedDocumentsType.ts | 9 ++++++++ app/types/AppointmentType.ts | 16 +++++++++++++ lib/seeders/agenda.ts | 14 +++++------- lib/seeders/historial.ts | 30 +++++++++++++++++-------- 9 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 app/components/UI/Counter.tsx create mode 100644 app/components/UI/Icons/LoaderIcon.tsx create mode 100644 app/components/UI/StatusPill.tsx create mode 100644 app/components/UI/UserIcon.tsx create mode 100644 app/types/AcceptedDocumentsType.ts create mode 100644 app/types/AppointmentType.ts diff --git a/app/components/Forms/FormInput.tsx b/app/components/Forms/FormInput.tsx index 63ff9f5..ed6652a 100644 --- a/app/components/Forms/FormInput.tsx +++ b/app/components/Forms/FormInput.tsx @@ -1,5 +1,4 @@ import { InputType } from "@/Types/InputTypes"; - interface Props { name: string; title?: string; @@ -8,7 +7,10 @@ interface Props { placeholder?: string; value?: string | number; isDisabled?: boolean; + multiple?: boolean; children?: React.ReactNode; + onChange?: (e: React.ChangeEvent) => void; + accept?: string; } export default function FormInput({ name, @@ -18,7 +20,10 @@ export default function FormInput({ placeholder, value, isDisabled, + multiple, children, + onChange, + accept }: Props) { return (
@@ -36,6 +41,9 @@ export default function FormInput({ disabled={isDisabled} aria-describedby="helper-text-explanation" step="any" + multiple={multiple} + accept={accept} + onChange={onChange} className={`w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-[#5C6B73] focus:border-[#5C6B73] dark:border-2 dark:border-[#9DB4C0] dark:text-[#E0FBFC] flex-1 min-w-50 diff --git a/app/components/UI/Counter.tsx b/app/components/UI/Counter.tsx new file mode 100644 index 0000000..7ff30af --- /dev/null +++ b/app/components/UI/Counter.tsx @@ -0,0 +1,15 @@ +interface Props { + count: number + children: string +} + +export default function Counter({ count, children }: Props) { + return ( +
+

+ {count} +

+ {children} +
+ ) +} \ No newline at end of file diff --git a/app/components/UI/Icons/LoaderIcon.tsx b/app/components/UI/Icons/LoaderIcon.tsx new file mode 100644 index 0000000..ce0d284 --- /dev/null +++ b/app/components/UI/Icons/LoaderIcon.tsx @@ -0,0 +1,7 @@ +import { LoaderCircle } from "lucide-react"; + +export default function LoaderIcon(){ + return ( + + ) +} \ No newline at end of file diff --git a/app/components/UI/StatusPill.tsx b/app/components/UI/StatusPill.tsx new file mode 100644 index 0000000..ef710e1 --- /dev/null +++ b/app/components/UI/StatusPill.tsx @@ -0,0 +1,31 @@ +import { CheckCircle, LoaderCircle, Pickaxe, TriangleAlert, XCircle } from "lucide-react" +import LoaderIcon from "./Icons/LoaderIcon" + +const colorClasses = { + red: "bg-red-500/30 dark:bg-red-600/30 text-red-500 border-red-500", + blue: "bg-blue-500/30 dark:bg-blue-600/30 text-blue-500 border-blue-500", + green: "bg-emerald-500/30 dark:bg-emerald-600/30 text-green-500 border-green-500", + yellow: "bg-amber-500/30 dark:bg-amber-600/30 text-amber-500 border-amber-500", +} +const colorIcons = { + red: XCircle, + blue: LoaderIcon, + green: CheckCircle, + yellow: TriangleAlert, +} + +export default function StatusPill({ + status, + color, +}: { + status: string + color: "red" | "blue" | "green" | "yellow" +}) { + const Icon = colorIcons[color] + return ( + + +

{status}

+
+ ) +} \ No newline at end of file diff --git a/app/components/UI/UserIcon.tsx b/app/components/UI/UserIcon.tsx new file mode 100644 index 0000000..5cd61af --- /dev/null +++ b/app/components/UI/UserIcon.tsx @@ -0,0 +1,9 @@ +import { User } from "lucide-react"; + +export default function UserIcon() { + return ( +
+ +
+ ); +} diff --git a/app/types/AcceptedDocumentsType.ts b/app/types/AcceptedDocumentsType.ts new file mode 100644 index 0000000..2bc5125 --- /dev/null +++ b/app/types/AcceptedDocumentsType.ts @@ -0,0 +1,9 @@ +export type AcceptedDocuments = + | "application/pdf" + | "application/msword" + | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + | "application/vnd.ms-excel" + | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + | "application/vnd.ms-powerpoint" + | "application/vnd.openxmlformats-officedocument.presentationml.presentation" + | "text/plain"; diff --git a/app/types/AppointmentType.ts b/app/types/AppointmentType.ts new file mode 100644 index 0000000..71c85b8 --- /dev/null +++ b/app/types/AppointmentType.ts @@ -0,0 +1,16 @@ +import { AcceptedDocuments } from "./AcceptedDocumentsType"; + +export type AppointmentStatus = "pendiente" | "completada" | "cancelada"; + +export type Appointment = { + id: string; + matricula_paciente: string; + matricula_doctor: string; + nombre_paciente: string; + fecha: string; + estatus: AppointmentStatus; + diagnostico?: string; + tratamiento?: string; + medico_responsable?: string; + documents?: AcceptedDocuments[]; +}; \ No newline at end of file diff --git a/lib/seeders/agenda.ts b/lib/seeders/agenda.ts index d8ab2d7..1a823a4 100644 --- a/lib/seeders/agenda.ts +++ b/lib/seeders/agenda.ts @@ -1,13 +1,6 @@ -export type Cita = { - id: string; - matricula_doctor: string; - matricula_paciente: string; - nombre_paciente: string; - fecha: string; - estatus: "pendiente" | "completada" | "cancelada"; -}; +import { Appointment } from "@/Types/AppointmentType"; -export const agendaSeed: Cita[] = [ +export const agendaSeed: Appointment[] = [ { id: "a-001", matricula_doctor: "DOC-001", @@ -23,6 +16,9 @@ export const agendaSeed: Cita[] = [ nombre_paciente: "María López", fecha: "2026-03-09", estatus: "completada", + diagnostico: "Hipertensión leve", + tratamiento: "Dieta baja en sodio y ejercicio moderado", + medico_responsable: "DOC-001", }, { id: "a-003", diff --git a/lib/seeders/historial.ts b/lib/seeders/historial.ts index bee1101..95a799b 100644 --- a/lib/seeders/historial.ts +++ b/lib/seeders/historial.ts @@ -1,25 +1,25 @@ -export type Consulta = { - id: string; - matricula_paciente: string; - fecha: string; - diagnostico: string; - tratamiento: string; - medico_responsable: string; -}; +import { Appointment } from "@/Types/AppointmentType"; -export const historialSeed: Consulta[] = [ +export const historialSeed: Appointment[] = [ { id: "c-001", matricula_paciente: "PAC-001", + matricula_doctor: "DOC-001", + nombre_paciente: "Juan García", fecha: "2025-01-15", + estatus: "completada", diagnostico: "Hipertensión arterial leve", tratamiento: "Losartán 50mg cada 24 horas", medico_responsable: "Dr. Carlos Méndez", + documents: [] }, { id: "c-002", matricula_paciente: "PAC-001", + matricula_doctor: "DOC-002", + nombre_paciente: "Juan García", fecha: "2025-03-02", + estatus: "completada", diagnostico: "Infección respiratoria aguda", tratamiento: "Amoxicilina 500mg cada 8 horas por 7 días", medico_responsable: "Dra. Laura Ríos", @@ -27,7 +27,10 @@ export const historialSeed: Consulta[] = [ { id: "c-003", matricula_paciente: "PAC-001", + matricula_doctor: "DOC-001", + nombre_paciente: "Juan García", fecha: "2025-06-20", + estatus: "completada", diagnostico: "Gastritis crónica", tratamiento: "Omeprazol 20mg en ayunas por 30 días", medico_responsable: "Dr. Carlos Méndez", @@ -35,7 +38,10 @@ export const historialSeed: Consulta[] = [ { id: "c-004", matricula_paciente: "PAC-002", + matricula_doctor: "DOC-002", + nombre_paciente: "María López", fecha: "2025-02-10", + estatus: "completada", diagnostico: "Diabetes tipo 2", tratamiento: "Metformina 850mg con cada comida", medico_responsable: "Dra. Laura Ríos", @@ -43,7 +49,10 @@ export const historialSeed: Consulta[] = [ { id: "c-005", matricula_paciente: "PAC-002", + matricula_doctor: "DOC-002", + nombre_paciente: "María López", fecha: "2025-04-18", + estatus: "completada", diagnostico: "Control glucémico", tratamiento: "Ajuste de dosis: Metformina 1000mg", medico_responsable: "Dra. Laura Ríos", @@ -51,7 +60,10 @@ export const historialSeed: Consulta[] = [ { id: "c-006", matricula_paciente: "PAC-002", + matricula_doctor: "DOC-001", + nombre_paciente: "María López", fecha: "2025-07-05", + estatus: "completada", diagnostico: "Neuropatía diabética leve", tratamiento: "Vitamina B12 + control mensual", medico_responsable: "Dr. Carlos Méndez",