From c0694719809d084180a057a7cf9ed4e5bd79de4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Corr=C3=AAa=20Chaves?= Date: Thu, 12 Sep 2024 02:08:44 -0300 Subject: [PATCH] v0.2.0 (#33) * [DEV-41] add auto migration to envs (#26) * chore: updated .env.example * chore: added vscode extensions recommendations * chore: updated dependencies * chore: updated README * chore: updated dependencies * chore: moved tailwind import to js * chore: added tests to env variables * chore: added env vault config * chore: work on workflows * chore: updated bun lock * chore: updated dependencies * chore: force build step to bundle env * chore: force build step to bundle env * chore: updated dotenv-vault * feat: bumped vault version * chore: I give up on dotenv-vault * chore: removed vault from workflow * chore: updated envs to work on both states * [DEV-54] repository enhancements and utilities package (#29) * chore: upgraded dependencies * feat: added banner to readme * feat: added code of conduct * feat: added contributing guide * test: move md files to github dir * chore: renamed contributing to github standard * feat: added screenshot to readme * chore: updaded pr template * feat: added bug report issue template * feat: added base shared package * chore: moved api to js export * feat: finished api integration * chore: updated dependencies * chore: updated dependencies * feat: moved service and api to shared lib * chore: enhanced tests * feat: added tests * chore: added type tests to CICD * feat: added api tests * feat: added test type entry * chore: removed prisma ads * [DEV-12] Enhance profile creation page (#30) * chore: removed prisma ads * fix: 404 thrown on non localized pages * fix: missing textures on cards * feat: refactored profile form * feat: enhanced legal documents * feat: enhanced footer * chore: disabled prefetch * chore: enhanced app metadata * chore: enhanced app metadata * chore: enhanced app metadata * chore: enhanced app metadata * chore: enhanced not found page * chore: enhanced app metadata * fix: link inserting locale * chore: minor style fixes * chore: minor style fixes * feat: added update missing person status --- apps/app/package.json | 20 +-- apps/app/src/app/(app)/page.tsx | 21 ++-- .../src/app/(app)/profiles/[id]/edit/page.tsx | 82 ++++++------ apps/app/src/app/(app)/profiles/[id]/page.tsx | 24 ++-- .../app/(app)/profiles/_components/filter.tsx | 1 - apps/app/src/app/(app)/profiles/new/page.tsx | 9 +- apps/app/src/app/(auth)/layout.tsx | 4 +- apps/app/src/app/_components/footer.tsx | 4 +- apps/app/src/app/error.tsx | 4 +- apps/app/src/app/manifest.ts | 2 +- apps/app/src/components/share.tsx | 2 +- .../modules/general/dialogs/delete-dialog.tsx | 48 +++++++ apps/app/src/modules/profile/actions.ts | 20 ++- .../components/profile-form.contact.tsx | 2 +- .../components/profile-form.general.tsx | 117 +++++++++--------- .../profile/components/profile-form.tsx | 12 +- .../profile/dialogs/contact-dialog.tsx} | 2 +- .../modules/profile/dialogs/find-dialog.tsx | 68 ++++++++++ .../modules/profile/templates/template_01.tsx | 2 +- .../{components => dialogs}/report-dialog.tsx | 0 bun.lockb | Bin 335920 -> 334920 bytes package.json | 6 +- packages/config/package.json | 2 +- packages/ds/package.json | 19 +-- .../ds/src/components/form/field-list.tsx | 6 +- packages/ds/src/components/form/form.tsx | 21 +++- packages/ds/src/components/ui/button.tsx | 3 +- .../ds/src/components/ui/calendar-input.tsx | 5 +- packages/ds/src/components/ui/dialog.tsx | 25 +++- packages/ds/src/lib/form.ts | 3 + packages/env/package.json | 4 +- packages/schemas/package.json | 2 +- packages/schemas/src/schemas/profile.ts | 12 +- packages/services/package.json | 4 +- packages/services/src/services/profile.ts | 21 ++++ packages/services/src/services/user.ts | 8 +- packages/shared/package.json | 4 +- public/locales/en-US.json | 1 + public/locales/pt-BR.json | 1 + scripts/tests/package.json | 2 +- 40 files changed, 392 insertions(+), 201 deletions(-) create mode 100644 apps/app/src/modules/general/dialogs/delete-dialog.tsx rename apps/app/src/{app/(app)/profiles/[id]/_components/find-dialog.tsx => modules/profile/dialogs/contact-dialog.tsx} (98%) create mode 100644 apps/app/src/modules/profile/dialogs/find-dialog.tsx rename apps/app/src/modules/report/{components => dialogs}/report-dialog.tsx (100%) diff --git a/apps/app/package.json b/apps/app/package.json index d67b49a..23101f2 100644 --- a/apps/app/package.json +++ b/apps/app/package.json @@ -14,36 +14,36 @@ "postinstall": "cd ../../ && bun run postinstall" }, "dependencies": { - "@clerk/localizations": "^2.8.1", - "@clerk/nextjs": "^5.4.1", + "@clerk/localizations": "^3.0.1", + "@clerk/nextjs": "^5.5.2", "@react-pdf/renderer": "^3.4.4", "@repo/ds": "1.0.0", "@repo/env": "1.0.0", "@repo/schemas": "1.0.0", "@repo/services": "1.0.0", - "@tanstack/react-query": "^5.54.1", - "@tanstack/react-query-devtools": "^5.54.1", + "@tanstack/react-query": "^5.55.4", + "@tanstack/react-query-devtools": "^5.55.4", "@upstash/ratelimit": "^2.0.2", "@vercel/analytics": "^1.3.1", "@vercel/functions": "^1.4.1", "@vercel/kv": "^2.0.0", "@vercel/speed-insights": "^1.0.12", "@yamiassu/shared": "*", - "lucide-react": "^0.438.0", - "next": "^14.2.8", - "next-intl": "^3.19.0", + "lucide-react": "^0.439.0", + "next": "^14.2.10", + "next-intl": "^3.19.1", "react": "^18.3.1", "react-dom": "^18.3.1", "zod": "^3.23.8" }, "devDependencies": { "@repo/config": "0.0.0", - "@types/node": "^22.5.3", + "@types/node": "^22.5.4", "@types/react": "^18.3.5", "@types/react-dom": "^18.3.0", "autoprefixer": "^10.4.20", "postcss": "^8.4.45", - "tailwindcss": "^3.4.10", - "typescript": "^5.5.4" + "tailwindcss": "^3.4.11", + "typescript": "^5.6.2" } } diff --git a/apps/app/src/app/(app)/page.tsx b/apps/app/src/app/(app)/page.tsx index 92f9505..cac1156 100644 --- a/apps/app/src/app/(app)/page.tsx +++ b/apps/app/src/app/(app)/page.tsx @@ -11,17 +11,17 @@ import Image from "next/image"; export default function Page() { return ( - <> +
{/** * ### MARK: Hero */} -
+

@@ -35,7 +35,7 @@ export default function Page() { src="/images/arts/line_01.svg" alt="" fetchPriority="high" - className="absolute z-[-1] w-full !top-[70%]" + className="absolute z-[-1] w-full !top-[50%]" />

@@ -66,6 +66,7 @@ export default function Page() {
@@ -252,9 +253,9 @@ export default function Page() { */}
-

+

Perguntas frequentes -

+
- +
); } diff --git a/apps/app/src/app/(app)/profiles/[id]/edit/page.tsx b/apps/app/src/app/(app)/profiles/[id]/edit/page.tsx index 0903e10..ed72652 100644 --- a/apps/app/src/app/(app)/profiles/[id]/edit/page.tsx +++ b/apps/app/src/app/(app)/profiles/[id]/edit/page.tsx @@ -1,22 +1,17 @@ import { Link } from "@/lib/navigation"; import parallel from "@/lib/parallel"; +import DeleteModal from "@/modules/general/dialogs/delete-dialog"; import * as actions from "@/modules/profile/actions"; import ProfileForm from "@/modules/profile/components/profile-form"; +import FindDialog from "@/modules/profile/dialogs/find-dialog"; import { currentUser } from "@/modules/user/loaders"; -import Form from "@repo/ds/form/form"; import { Button, buttonVariants } from "@repo/ds/ui/button"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@repo/ds/ui/dialog"; -import type { ProfileUpdateSchema } from "@repo/schemas/profile"; +import type { + ProfileFindSchema, + ProfileUpdateSchema, +} from "@repo/schemas/profile"; import profileService from "@repo/services/profile"; -import { Eye, Trash } from "lucide-react"; +import { Eye, SaveIcon, Trash } from "lucide-react"; import { notFound } from "next/navigation"; export default async function Page({ params }: { params: { id: string } }) { @@ -33,6 +28,12 @@ export default async function Page({ params }: { params: { id: string } }) { return actions.update({ id: params.id, data: data as ProfileUpdateSchema }); } + async function find(data: ProfileFindSchema) { + "use server"; + + return actions.find({ id: params.id, data }); + } + async function remove() { "use server"; @@ -52,42 +53,31 @@ export default async function Page({ params }: { params: { id: string } }) { > - - - - - - - - Você tem certeza? - - Essa ação não é reversivel, os dados serão perdidos - permanentemente - - - - - - - -
- -
-
-
-
+ + + - - - Voltar - - + + + + + diff --git a/apps/app/src/app/(app)/profiles/[id]/page.tsx b/apps/app/src/app/(app)/profiles/[id]/page.tsx index 47f6c7e..a1b1586 100644 --- a/apps/app/src/app/(app)/profiles/[id]/page.tsx +++ b/apps/app/src/app/(app)/profiles/[id]/page.tsx @@ -3,7 +3,8 @@ import { Link } from "@/lib/navigation"; import parallel from "@/lib/parallel"; import { baseUrl } from "@/lib/url"; import Banner from "@/modules/profile/components/banner"; -import ReportDialog from "@/modules/report/components/report-dialog"; +import { ContactDialog } from "@/modules/profile/dialogs/contact-dialog"; +import ReportDialog from "@/modules/report/dialogs/report-dialog"; import { currentUser } from "@/modules/user/loaders"; import { Avatar, AvatarFallback, AvatarImage } from "@repo/ds/ui/avatar"; import { Button, buttonVariants } from "@repo/ds/ui/button"; @@ -27,7 +28,6 @@ import { getLocale, getTranslations } from "next-intl/server"; import { headers } from "next/headers"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { FindDialog } from "./_components/find-dialog"; /** * ### MARK: Metadata @@ -118,11 +118,9 @@ export default async function Page({ params }: { params: { id: string } }) {
- - - + + + {!canReport && ( {t("already_reported")} @@ -130,11 +128,7 @@ export default async function Page({ params }: { params: { id: string } }) {
- @@ -148,7 +142,7 @@ export default async function Page({ params }: { params: { id: string } }) { link={`${baseUrl()}/profiles/${data.id}`} description={t("help", { profile: data.name })} > - @@ -157,7 +151,7 @@ export default async function Page({ params }: { params: { id: string } }) { description={data.description} contact={data.contact?.options as { type: string; value: string }[]} > - @@ -172,7 +166,7 @@ export default async function Page({ params }: { params: { id: string } }) { > - diff --git a/apps/app/src/app/(app)/profiles/_components/filter.tsx b/apps/app/src/app/(app)/profiles/_components/filter.tsx index cf47333..6543978 100644 --- a/apps/app/src/app/(app)/profiles/_components/filter.tsx +++ b/apps/app/src/app/(app)/profiles/_components/filter.tsx @@ -67,7 +67,6 @@ export function Filter(props: Props) { Aplicar diff --git a/apps/app/src/app/(auth)/layout.tsx b/apps/app/src/app/(auth)/layout.tsx index b4be4c3..886b7a0 100644 --- a/apps/app/src/app/(auth)/layout.tsx +++ b/apps/app/src/app/(auth)/layout.tsx @@ -5,8 +5,8 @@ import Footer from "../_components/footer"; export default function Layout({ children }: { children: React.ReactNode }) { return ( <> -
- +
+ logo -
+
- + Ir para home diff --git a/apps/app/src/app/manifest.ts b/apps/app/src/app/manifest.ts index 875abb2..ca6e9a0 100644 --- a/apps/app/src/app/manifest.ts +++ b/apps/app/src/app/manifest.ts @@ -20,7 +20,7 @@ export async function generate(lang: string) { description: t("description"), start_url: "/", display: "browser", - background_color: "#DFF2FD", + background_color: "#3a506b", theme_color: "#3a506b", orientation: "portrait", dir: "ltr", diff --git a/apps/app/src/components/share.tsx b/apps/app/src/components/share.tsx index 8551055..94796ee 100644 --- a/apps/app/src/components/share.tsx +++ b/apps/app/src/components/share.tsx @@ -21,7 +21,7 @@ export default function Share(props: Props) { return ( - {props.children || } + {props.children || } Promise; + children: React.ReactNode; + + title?: string; + description?: string; +} + +export default function DeleteDialog(props: Props) { + return ( + + {props.children} + + + + {props.title || "Você tem certeza?"} + + {props.description || + "Essa ação não é reversivel, os dados serão perdidos permanentemente"} + + + + + + + +
+ +
+
+
+
+ ); +} diff --git a/apps/app/src/modules/profile/actions.ts b/apps/app/src/modules/profile/actions.ts index 90e80f4..5a34483 100644 --- a/apps/app/src/modules/profile/actions.ts +++ b/apps/app/src/modules/profile/actions.ts @@ -2,8 +2,9 @@ import api, { apiService } from "@/lib/api"; import pagination from "@repo/schemas/pagination"; -import { profileStoreSchema, profileUpdateSchema } from "@repo/schemas/profile"; +import { profileFindSchema, profileStoreSchema, profileUpdateSchema } from "@repo/schemas/profile"; import profileService from "@repo/services/profile"; +import { revalidatePath } from "next/cache"; import { z } from "zod"; export const index = api @@ -20,9 +21,20 @@ export const store = api export const update = api .zod(z.object({ id: z.string().cuid(), data: profileUpdateSchema })) .action(apiService(profileService.update)) - .action(async () => ({ - reload: true, - })); + .action(async () => { + revalidatePath("/", "layout") + + return { message: "yay" } + }); + +export const find = api + .zod(z.object({ data: profileFindSchema, id: z.string() })) + .action(apiService(profileService.find)) + .action(async () => { + revalidatePath("/", "layout") + + return { message: "yay" } + }); export const remove = api .zod(z.string()) diff --git a/apps/app/src/modules/profile/components/profile-form.contact.tsx b/apps/app/src/modules/profile/components/profile-form.contact.tsx index d1f14fc..60a881d 100644 --- a/apps/app/src/modules/profile/components/profile-form.contact.tsx +++ b/apps/app/src/modules/profile/components/profile-form.contact.tsx @@ -63,7 +63,7 @@ export default function ProfileFormContact() { className="m-0 w-full" render={({ field }) => } /> -
diff --git a/apps/app/src/modules/profile/components/profile-form.general.tsx b/apps/app/src/modules/profile/components/profile-form.general.tsx index de4074d..bf1ec58 100644 --- a/apps/app/src/modules/profile/components/profile-form.general.tsx +++ b/apps/app/src/modules/profile/components/profile-form.general.tsx @@ -19,66 +19,71 @@ export default function ProfileFormGeneral() { return ( - { - return ; - }} - /> +
+
+ { + return ; + }} + /> + } + /> +
- } - /> +
+ { + return ; + }} + /> - { - return ; - }} - /> + { + return ; + }} + /> - { - return ; - }} - /> + { + return ( + - - - - - - - {t("general.gender-options.male")} - - - {t("general.gender-options.female")} - - - {t("general.gender-options.other")} - - - - ); - }} - /> + + + {t("general.gender-options.male")} + + + {t("general.gender-options.female")} + + + {t("general.gender-options.other")} + + + + ); + }} + /> +
+
-
+
{props.children}
diff --git a/apps/app/src/app/(app)/profiles/[id]/_components/find-dialog.tsx b/apps/app/src/modules/profile/dialogs/contact-dialog.tsx similarity index 98% rename from apps/app/src/app/(app)/profiles/[id]/_components/find-dialog.tsx rename to apps/app/src/modules/profile/dialogs/contact-dialog.tsx index 6dec3d1..de349a2 100644 --- a/apps/app/src/app/(app)/profiles/[id]/_components/find-dialog.tsx +++ b/apps/app/src/modules/profile/dialogs/contact-dialog.tsx @@ -17,7 +17,7 @@ interface Props { } | null; } -export function FindDialog(props: Props) { +export function ContactDialog(props: Props) { const options = props.contact?.options as { type: string; value: string }[]; return ( diff --git a/apps/app/src/modules/profile/dialogs/find-dialog.tsx b/apps/app/src/modules/profile/dialogs/find-dialog.tsx new file mode 100644 index 0000000..5f439e9 --- /dev/null +++ b/apps/app/src/modules/profile/dialogs/find-dialog.tsx @@ -0,0 +1,68 @@ +"use client"; + +import Field from "@repo/ds/form/field"; +import Form from "@repo/ds/form/form"; +import { Button } from "@repo/ds/ui/button"; +import { CalendarInput } from "@repo/ds/ui/calendar-input"; +import { + Dialog, + DialogContent, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@repo/ds/ui/dialog"; +import { + type ProfileFindSchema, + profileFindSchema, +} from "@repo/schemas/profile"; +import { useTranslations } from "next-intl"; + +interface Props { + submit: (data: ProfileFindSchema) => Promise; + children: React.ReactNode; + + title?: string; + description?: string; +} + +export default function FindDialog(props: Props) { + const t = useTranslations("profiles.new"); + + return ( + + {props.children} + + +

Informação atualizada

} + > + + {props.title || "Você tem certeza?"} + + + } + /> + + + + + + + + +
+
+ ); +} diff --git a/apps/app/src/modules/profile/templates/template_01.tsx b/apps/app/src/modules/profile/templates/template_01.tsx index fc13d31..4f1ccf3 100644 --- a/apps/app/src/modules/profile/templates/template_01.tsx +++ b/apps/app/src/modules/profile/templates/template_01.tsx @@ -30,7 +30,7 @@ export default function Template01(props: Props) { return ( - Desaparecida + Procura-se {(props.images?.length || 0) > 0 && ( )} diff --git a/apps/app/src/modules/report/components/report-dialog.tsx b/apps/app/src/modules/report/dialogs/report-dialog.tsx similarity index 100% rename from apps/app/src/modules/report/components/report-dialog.tsx rename to apps/app/src/modules/report/dialogs/report-dialog.tsx diff --git a/bun.lockb b/bun.lockb index add4aac92b1a7022d08a73eeb9b84dc74a61fe04..88344c2235376fbcca1bf544e25a243c37dec755 100644 GIT binary patch delta 30842 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 delta 31546 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 CQ+9j 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 diff --git a/package.json b/package.json index c47cac8..95f3eb9 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,11 @@ "bun": ">=1.1.0" }, "packageManager": "yarn@1.22.22", - "workspaces": ["apps/*", "packages/*", "scripts/*"], + "workspaces": [ + "apps/*", + "packages/*", + "scripts/*" + ], "dependencies": { "@dotenvx/dotenvx": "^1.14.0", "symlink-dir": "^6.0.2", diff --git a/packages/config/package.json b/packages/config/package.json index 4560678..d933264 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -6,7 +6,7 @@ "@yamiassu/shared": "*" }, "devDependencies": { - "typescript": "^5.5.4" + "typescript": "^5.6.2" }, "license": "MIT", "publishConfig": { diff --git a/packages/ds/package.json b/packages/ds/package.json index 53da155..739d379 100644 --- a/packages/ds/package.json +++ b/packages/ds/package.json @@ -2,7 +2,9 @@ "name": "@repo/ds", "version": "1.0.0", "private": true, - "sideEffects": ["**/*.css"], + "sideEffects": [ + "**/*.css" + ], "exports": { "./*": "./src/components/*.tsx", "./utils": "./src/lib/utils.ts", @@ -24,10 +26,10 @@ "autoprefixer": "^10.4.20", "postcss": "^8.4.45", "react": "^18.3.1", - "tailwindcss": "^3.4.10", + "tailwindcss": "^3.4.11", "tailwindcss-animate": "^1.0.7", - "typescript": "^5.5.4", - "vite": "^5.4.3", + "typescript": "^5.6.2", + "vite": "^5.4.4", "webpack": "^5.94.0" }, "dependencies": { @@ -44,15 +46,16 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tabs": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.2", - "@tanstack/react-query": "^5.54.1", + "@radix-ui/react-use-controllable-state": "^1.1.0", + "@tanstack/react-query": "^5.55.4", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cmdk": "^1.0.0", "date-fns": "^3.6.0", "embla-carousel-react": "^8.2.1", - "lucide-react": "^0.438.0", - "next": "^14.2.8", - "next-intl": "^3.19.0", + "lucide-react": "^0.439.0", + "next": "^14.2.10", + "next-intl": "^3.19.1", "next-themes": "^0.3.0", "react": "^18.3.1", "react-day-picker": "^8.10.1", diff --git a/packages/ds/src/components/form/field-list.tsx b/packages/ds/src/components/form/field-list.tsx index 33147cd..ebbd5d5 100644 --- a/packages/ds/src/components/form/field-list.tsx +++ b/packages/ds/src/components/form/field-list.tsx @@ -25,11 +25,7 @@ export default function FieldList(props: Props) { }), )} - diff --git a/packages/ds/src/components/form/form.tsx b/packages/ds/src/components/form/form.tsx index d9f07a8..b1bde81 100644 --- a/packages/ds/src/components/form/form.tsx +++ b/packages/ds/src/components/form/form.tsx @@ -6,8 +6,9 @@ import { FormProvider, useForm } from "react-hook-form"; import { objectToFormData } from "../../lib/form"; import type React from "react"; -import { createElement, useState } from "react"; +import { createElement, useEffect, useState } from "react"; import type { ZodSchema } from "zod"; +import { useModal } from "../ui/dialog"; interface FormProps { onSubmit?: (data: any, raw: Record) => any | Promise; @@ -28,11 +29,16 @@ export default function Form(props: FormProps) { const router = useRouter(); const pathname = usePathname(); const [replace, setreplace] = useState(undefined); + const [, setModal] = useModal(); const form = useForm({ defaultValues: props.data || props.defaultData, resolver: props.schema && zodResolver(props.schema), }); + useEffect(() => { + form.reset(props.data); + }, [props.data, form.reset]); + return (

{ + onSubmit={async (event) => { + const payload = form.getValues(); if (!props.onSubmit) return; + event?.stopPropagation(); + event?.preventDefault(); form.clearErrors(); const response = await props .onSubmit(objectToFormData(payload), payload) .catch((e: unknown) => e); - const errors = response?.errors || response?.data?.errors; + const errors = + response?.[0] || response?.errors || response?.data?.errors; if (!response) return; @@ -60,14 +70,15 @@ export default function Form(props: FormProps) { return; } - const data = response?.data || response; + const data = response?.[1] || response?.data || response; + setModal(false); if (data.redirect) return router.push(data.redirect); if (data.reload) return router.push(pathname); if (data.replace && props.replace) return setreplace(data); return props?.onSuccess?.(data); - })} + }} className={props.className} > {replace diff --git a/packages/ds/src/components/ui/button.tsx b/packages/ds/src/components/ui/button.tsx index 94d674a..84b026b 100644 --- a/packages/ds/src/components/ui/button.tsx +++ b/packages/ds/src/components/ui/button.tsx @@ -19,7 +19,7 @@ const buttonVariants = cva( secondary: "bg-[#6fffe9] text-[#183043]-foreground hover:bg-[#6fffe9]/80", ghost: "hover:bg-accent hover:text-accent-foreground", - success: "bg-green-500 text-[#26313f] hover:bg-bg-green-500/90", + success: "bg-green-500 text-white hover:bg-bg-green-500/90", link: "text-primary underline-offset-4 hover:underline", }, size: { @@ -50,6 +50,7 @@ const Button = React.forwardRef( className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} + type={props.type || "button"} /> ); }, diff --git a/packages/ds/src/components/ui/calendar-input.tsx b/packages/ds/src/components/ui/calendar-input.tsx index 879851f..97c99e7 100644 --- a/packages/ds/src/components/ui/calendar-input.tsx +++ b/packages/ds/src/components/ui/calendar-input.tsx @@ -6,11 +6,12 @@ import { Popover, PopoverContent, PopoverTrigger } from "./popover"; interface Props extends Omit { mode?: "range" | "single"; + modal?: boolean; } -export function CalendarInput({ mode, ...field }: Props) { +export function CalendarInput({ mode, modal, ...field }: Props) { return ( - +