refactor: remove unused UI and runtime scaffolding

This commit is contained in:
Amruth Pillai
2026-09-07 22:40:50 +02:00
parent ad91a0838c
commit 4f60856706
16 changed files with 72 additions and 573 deletions
-4
View File
@@ -59,10 +59,6 @@ jobs:
- name: Checkout Repository
uses: actions/checkout@v6
- name: Get version from package.json
id: version
run: echo "version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v4
+1 -2
View File
@@ -4,7 +4,7 @@
"type": "module",
"private": true,
"scripts": {
"build": "rimraf dist && vite build",
"build": "vite build",
"dev": "vite dev",
"serve": "vite preview",
"start": "vite preview",
@@ -118,7 +118,6 @@
"@vitejs/plugin-react": "^6.1.1",
"babel-plugin-macros": "^3.1.0",
"babel-plugin-react-compiler": "^1.0.0",
"rimraf": "^6.1.3",
"typescript": "^7.0.2",
"vite": "^8.2.2"
}
-3
View File
@@ -1,3 +0,0 @@
import z from "zod";
export const apiKeyDialogSchemas = [z.object({ type: z.literal("api-key.create"), data: z.undefined() })] as const;
-7
View File
@@ -1,7 +0,0 @@
import z from "zod";
export const authDialogSchemas = [
z.object({ type: z.literal("auth.change-password"), data: z.undefined() }),
z.object({ type: z.literal("auth.two-factor.enable"), data: z.undefined() }),
z.object({ type: z.literal("auth.two-factor.disable"), data: z.undefined() }),
] as const;
-152
View File
@@ -1,152 +0,0 @@
import z from "zod";
import {
awardItemSchema,
certificationItemSchema,
coverLetterItemSchema,
customSectionSchema,
educationItemSchema,
experienceItemSchema,
interestItemSchema,
languageItemSchema,
profileItemSchema,
projectItemSchema,
publicationItemSchema,
referenceItemSchema,
skillItemSchema,
summaryItemSchema,
volunteerItemSchema,
} from "@reactive-resume/schema/resume/data";
export const resumeDialogSchemas = [
z.object({ type: z.literal("resume.create"), data: z.undefined() }),
z.object({
type: z.literal("resume.update"),
data: z.object({ id: z.string(), name: z.string(), slug: z.string(), tags: z.array(z.string()) }),
}),
z.object({ type: z.literal("resume.import"), data: z.undefined() }),
z.object({
type: z.literal("resume.duplicate"),
data: z.object({
id: z.string(),
name: z.string(),
slug: z.string(),
tags: z.array(z.string()),
shouldRedirect: z.boolean().optional(),
}),
}),
z.object({ type: z.literal("resume.template.gallery"), data: z.undefined() }),
z.object({
type: z.literal("resume.sections.profiles.create"),
data: z.object({ item: profileItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.profiles.update"),
data: z.object({ item: profileItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.experience.create"),
data: z.object({ item: experienceItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.experience.update"),
data: z.object({ item: experienceItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.education.create"),
data: z.object({ item: educationItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.education.update"),
data: z.object({ item: educationItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.projects.create"),
data: z.object({ item: projectItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.projects.update"),
data: z.object({ item: projectItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.skills.create"),
data: z.object({ item: skillItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.skills.update"),
data: z.object({ item: skillItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.languages.create"),
data: z.object({ item: languageItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.languages.update"),
data: z.object({ item: languageItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.awards.create"),
data: z.object({ item: awardItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.awards.update"),
data: z.object({ item: awardItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.certifications.create"),
data: z.object({ item: certificationItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.certifications.update"),
data: z.object({ item: certificationItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.publications.create"),
data: z.object({ item: publicationItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.publications.update"),
data: z.object({ item: publicationItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.interests.create"),
data: z.object({ item: interestItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.interests.update"),
data: z.object({ item: interestItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.volunteer.create"),
data: z.object({ item: volunteerItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.volunteer.update"),
data: z.object({ item: volunteerItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.references.create"),
data: z.object({ item: referenceItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.references.update"),
data: z.object({ item: referenceItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.summary.create"),
data: z.object({ item: summaryItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.summary.update"),
data: z.object({ item: summaryItemSchema, customSectionId: z.string().optional() }),
}),
z.object({
type: z.literal("resume.sections.cover-letter.create"),
data: z.object({ item: coverLetterItemSchema.optional(), customSectionId: z.string().optional() }).optional(),
}),
z.object({
type: z.literal("resume.sections.cover-letter.update"),
data: z.object({ item: coverLetterItemSchema, customSectionId: z.string().optional() }),
}),
z.object({ type: z.literal("resume.sections.custom.create"), data: customSectionSchema.optional() }),
z.object({ type: z.literal("resume.sections.custom.update"), data: customSectionSchema }),
] as const;
+51 -12
View File
@@ -1,19 +1,58 @@
import z from "zod";
import { apiKeyDialogSchemas } from "./api-key/schema";
import { authDialogSchemas } from "./auth/schema";
import { resumeDialogSchemas } from "./resume/schema";
import type { CoverLetterItem, CustomSection, SectionItem, SummaryItem } from "@reactive-resume/schema/resume/data";
export const dialogSchemaRegistries = [
{ domain: "auth", schemas: authDialogSchemas },
{ domain: "api-key", schemas: apiKeyDialogSchemas },
{ domain: "resume", schemas: resumeDialogSchemas },
] as const;
type EmptyDialog<T extends string> = { [K in T]: { type: K; data?: undefined } }[T];
const dialogSchemaEntries = [...authDialogSchemas, ...apiKeyDialogSchemas, ...resumeDialogSchemas] as const;
type SectionItems = {
profiles: SectionItem<"profiles">;
experience: SectionItem<"experience">;
education: SectionItem<"education">;
projects: SectionItem<"projects">;
skills: SectionItem<"skills">;
languages: SectionItem<"languages">;
interests: SectionItem<"interests">;
awards: SectionItem<"awards">;
certifications: SectionItem<"certifications">;
publications: SectionItem<"publications">;
volunteer: SectionItem<"volunteer">;
references: SectionItem<"references">;
summary: SummaryItem;
"cover-letter": CoverLetterItem;
};
export const dialogTypeSchema = z.discriminatedUnion("type", dialogSchemaEntries);
type SectionDialog = {
[T in keyof SectionItems]:
| {
type: `resume.sections.${T}.create`;
data?: { item?: SectionItems[T]; customSectionId?: string };
}
| {
type: `resume.sections.${T}.update`;
data: { item: SectionItems[T]; customSectionId?: string };
};
}[keyof SectionItems];
export type DialogSchema =
| EmptyDialog<
| "auth.change-password"
| "auth.two-factor.enable"
| "auth.two-factor.disable"
| "api-key.create"
| "resume.create"
| "resume.import"
| "resume.template.gallery"
>
| {
type: "resume.update";
data: { id: string; name: string; slug: string; tags: string[] };
}
| {
type: "resume.duplicate";
data: { id: string; name: string; slug: string; tags: string[]; shouldRedirect?: boolean };
}
| SectionDialog
| { type: "resume.sections.custom.create"; data?: CustomSection }
| { type: "resume.sections.custom.update"; data: CustomSection };
export type DialogSchema = z.infer<typeof dialogTypeSchema>;
export type DialogType = DialogSchema["type"];
export type DialogData<T extends DialogType> = Extract<DialogSchema, { type: T }>["data"];
-8
View File
@@ -1,5 +1,4 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { dialogSchemaRegistries, dialogTypeSchema } from "./schemas";
import { useDialogStore } from "./store";
describe("useDialogStore", () => {
@@ -14,13 +13,6 @@ describe("useDialogStore", () => {
});
describe("openDialog", () => {
it("uses schema entries from domain registries", () => {
expect(dialogSchemaRegistries.map((registry) => registry.domain)).toEqual(["auth", "api-key", "resume"]);
expect(dialogTypeSchema.options).toHaveLength(
dialogSchemaRegistries.reduce((total, registry) => total + registry.schemas.length, 0),
);
});
it("opens a dialog and sets activeDialog", () => {
useDialogStore.getState().openDialog("api-key.create", undefined);
@@ -1,5 +1,5 @@
import type { AgentUIMessage } from "@reactive-resume/ai/tools/agent-tool-contracts";
import type { UIMessage, UIMessageChunk } from "ai";
import type { UIMessage } from "ai";
import type * as React from "react";
import type { RouterOutput } from "@/libs/orpc/client";
import type { PatchApprovalResponse } from "./patch-approval-card";
@@ -25,7 +25,12 @@ import {
} from "@phosphor-icons/react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useNavigate } from "@tanstack/react-router";
import { lastAssistantMessageIsCompleteWithApprovalResponses, lastAssistantMessageIsCompleteWithToolCalls } from "ai";
import {
lastAssistantMessageIsCompleteWithApprovalResponses,
lastAssistantMessageIsCompleteWithToolCalls,
parseJsonEventStream,
uiMessageChunkSchema,
} from "ai";
import { m } from "motion/react";
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import ReactMarkdown from "react-markdown";
@@ -348,34 +353,18 @@ function textFromMessage(message: UIMessage) {
}
function parseAgentSseStream(stream: ReadableStream<string>) {
let buffer = "";
const eventBoundary = /\r?\n\r?\n/;
return stream.pipeThrough(
new TransformStream<string, UIMessageChunk>({
return parseJsonEventStream({
stream: stream.pipeThrough(new TextEncoderStream()),
schema: uiMessageChunkSchema,
}).pipeThrough(
new TransformStream({
transform(chunk, controller) {
buffer += chunk;
let boundary = eventBoundary.exec(buffer);
while (boundary) {
const event = buffer.slice(0, boundary.index);
buffer = buffer.slice(boundary.index + boundary[0].length);
for (const line of event.split(/\r?\n/)) {
if (!line.startsWith("data:")) continue;
const data = line.slice("data:".length).trimStart();
if (!data || data === "[DONE]") continue;
try {
controller.enqueue(JSON.parse(data) as UIMessageChunk);
} catch (error) {
console.warn("[agent] dropping malformed SSE frame", error);
}
}
boundary = eventBoundary.exec(buffer);
if (!chunk.success) {
console.warn("[agent] dropping malformed SSE frame", chunk.error);
return;
}
controller.enqueue(chunk.value);
},
}),
);
+1 -67
View File
@@ -1,10 +1,7 @@
import type { VariantProps } from "class-variance-authority";
import type * as React from "react";
import { mergeProps } from "@base-ui/react/merge-props";
import { useRender } from "@base-ui/react/use-render";
import { cva } from "class-variance-authority";
import { cn } from "@reactive-resume/utils/style";
import { Button } from "./button";
const attachmentVariants = cva(
"group/attachment relative flex w-fit min-w-0 max-w-full shrink-0 flex-wrap rounded-xl border bg-card text-card-foreground transition-colors focus-within:ring-1 focus-within:ring-ring/50 has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed",
@@ -103,59 +100,6 @@ function AttachmentTitle({ className, ...props }: React.ComponentProps<"span">)
);
}
function AttachmentDescription({ className, ...props }: React.ComponentProps<"span">) {
return (
<span
data-slot="attachment-description"
className={cn(
"mt-0.5 block min-w-0 max-w-full truncate text-muted-foreground text-xs group-data-[state=error]/attachment:text-destructive/80",
className,
)}
{...props}
/>
);
}
function AttachmentActions({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="attachment-actions"
className={cn(
"relative z-20 flex shrink-0 items-center group-data-[orientation=vertical]/attachment:absolute group-data-[orientation=vertical]/attachment:top-3 group-data-[orientation=vertical]/attachment:right-3 group-data-[orientation=vertical]/attachment:gap-1",
className,
)}
{...props}
/>
);
}
function AttachmentAction({ className, variant, size = "icon-xs", ...props }: React.ComponentProps<typeof Button>) {
return (
<Button
data-slot="attachment-action"
variant={variant ?? "ghost"}
size={size}
className={cn(className)}
{...props}
/>
);
}
function AttachmentTrigger({ className, type, render, ...props }: useRender.ComponentProps<"button">) {
return useRender({
defaultTagName: "button",
props: mergeProps<"button">(
{
type: type ?? "button",
className: cn("absolute inset-0 z-10 outline-none", className),
},
props,
),
render,
state: { slot: "attachment-trigger" },
});
}
function AttachmentGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
@@ -169,14 +113,4 @@ function AttachmentGroup({ className, ...props }: React.ComponentProps<"div">) {
);
}
export {
Attachment,
AttachmentAction,
AttachmentActions,
AttachmentContent,
AttachmentDescription,
AttachmentGroup,
AttachmentMedia,
AttachmentTitle,
AttachmentTrigger,
};
export { Attachment, AttachmentContent, AttachmentGroup, AttachmentMedia, AttachmentTitle };
+1 -45
View File
@@ -5,10 +5,6 @@ import { useRender } from "@base-ui/react/use-render";
import { cva } from "class-variance-authority";
import { cn } from "@reactive-resume/utils/style";
function BubbleGroup({ className, ...props }: React.ComponentProps<"div">) {
return <div data-slot="bubble-group" className={cn("flex min-w-0 flex-col gap-2", className)} {...props} />;
}
const bubbleVariants = cva(
"group/bubble relative flex w-fit min-w-0 max-w-[80%] flex-col gap-1 data-[variant=ghost]:max-w-full data-[align=end]:self-end group-data-[align=end]/message:self-end",
{
@@ -72,44 +68,4 @@ function BubbleContent({ className, render, ...props }: useRender.ComponentProps
});
}
const bubbleReactionsVariants = cva(
"absolute z-10 flex w-fit shrink-0 items-center justify-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-sm ring-3 ring-card has-[button]:p-0",
{
variants: {
side: {
top: "top-0 -translate-y-3/4",
bottom: "bottom-0 translate-y-3/4",
},
align: {
start: "left-3",
end: "right-3",
},
},
defaultVariants: {
side: "bottom",
align: "end",
},
},
);
function BubbleReactions({
side = "bottom",
align = "end",
className,
...props
}: React.ComponentProps<"div"> & {
align?: "start" | "end";
side?: "top" | "bottom";
}) {
return (
<div
data-slot="bubble-reactions"
data-align={align}
data-side={side}
className={cn(bubbleReactionsVariants({ side, align }), className)}
{...props}
/>
);
}
export { Bubble, BubbleContent, BubbleGroup, BubbleReactions };
export { Bubble, BubbleContent };
-33
View File
@@ -1,7 +1,6 @@
import { Combobox as ComboboxPrimitive } from "@base-ui/react";
import { CaretDownIcon, CheckIcon, XIcon } from "@phosphor-icons/react";
import * as React from "react";
import { Button } from "@reactive-resume/ui/components/button";
import {
InputGroup,
InputGroupAddon,
@@ -202,37 +201,6 @@ function ComboboxChips({
);
}
function ComboboxChip({
className,
children,
showRemove = true,
...props
}: ComboboxPrimitive.Chip.Props & {
showRemove?: boolean;
}) {
return (
<ComboboxPrimitive.Chip
data-slot="combobox-chip"
className={cn(
"flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 whitespace-nowrap rounded-sm bg-muted px-1.5 font-medium text-foreground text-xs has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-data-[slot=combobox-chip-remove]:pe-0 has-disabled:opacity-50",
className,
)}
{...props}
>
{children}
{showRemove && (
<ComboboxPrimitive.ChipRemove
render={<Button variant="ghost" size="icon-xs" />}
className="-ms-1 opacity-50 hover:opacity-100"
data-slot="combobox-chip-remove"
>
<XIcon className="pointer-events-none" />
</ComboboxPrimitive.ChipRemove>
)}
</ComboboxPrimitive.Chip>
);
}
function ComboboxChipsInput({ className, ...props }: ComboboxPrimitive.Input.Props) {
return (
<ComboboxPrimitive.Input
@@ -248,7 +216,6 @@ function useComboboxAnchor() {
}
export {
ComboboxChip,
ComboboxChips,
ComboboxChipsInput,
ComboboxClear,
-38
View File
@@ -1,13 +1,6 @@
import type * as React from "react";
import { CheckIcon, MagnifyingGlassIcon } from "@phosphor-icons/react";
import { Command as CommandPrimitive } from "cmdk";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@reactive-resume/ui/components/dialog";
import { InputGroup, InputGroupAddon } from "@reactive-resume/ui/components/input-group";
import { cn } from "@reactive-resume/utils/style";
@@ -24,36 +17,6 @@ function Command({ className, ...props }: React.ComponentProps<typeof CommandPri
);
}
function CommandDialog({
title = "Command Palette",
description = "Search for a command to run...",
children,
className,
showCloseButton = false,
...props
}: Omit<React.ComponentProps<typeof Dialog>, "children"> & {
title?: string;
description?: string;
className?: string;
showCloseButton?: boolean;
children: React.ReactNode;
}) {
return (
<Dialog {...props}>
<DialogHeader className="sr-only">
<DialogTitle>{title}</DialogTitle>
<DialogDescription>{description}</DialogDescription>
</DialogHeader>
<DialogContent
className={cn("top-1/3 translate-y-0 animate-none! overflow-hidden rounded-xl! p-0", className)}
showCloseButton={showCloseButton}
>
{children}
</DialogContent>
</Dialog>
);
}
function CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>) {
return (
<div data-slot="command-input-wrapper" className="p-1 pb-0">
@@ -145,7 +108,6 @@ function CommandShortcut({ className, ...props }: React.ComponentProps<"span">)
export {
Command,
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
+1 -44
View File
@@ -1,10 +1,6 @@
import type * as React from "react";
import { cn } from "@reactive-resume/utils/style";
function MessageGroup({ className, ...props }: React.ComponentProps<"div">) {
return <div data-slot="message-group" className={cn("flex min-w-0 flex-col gap-2", className)} {...props} />;
}
function Message({ className, align = "start", ...props }: React.ComponentProps<"div"> & { align?: "start" | "end" }) {
return (
<div
@@ -19,19 +15,6 @@ function Message({ className, align = "start", ...props }: React.ComponentProps<
);
}
function MessageAvatar({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="message-avatar"
className={cn(
"flex w-fit min-w-8 shrink-0 items-center justify-center self-end overflow-hidden rounded-full bg-muted group-has-data-[slot=message-footer]/message:-translate-y-8",
className,
)}
{...props}
/>
);
}
function MessageContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
@@ -45,30 +28,4 @@ function MessageContent({ className, ...props }: React.ComponentProps<"div">) {
);
}
function MessageHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="message-header"
className={cn(
"flex min-w-0 max-w-full items-center px-3 font-medium text-muted-foreground text-xs group-has-data-[variant=ghost]/message:px-0",
className,
)}
{...props}
/>
);
}
function MessageFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="message-footer"
className={cn(
"flex min-w-0 max-w-full items-center px-3 font-medium text-muted-foreground text-xs group-has-data-[variant=ghost]/message:px-0 group-data-[align=end]/message:justify-end",
className,
)}
{...props}
/>
);
}
export { Message, MessageAvatar, MessageContent, MessageFooter, MessageGroup, MessageHeader };
export { Message, MessageContent };
@@ -15,16 +15,6 @@ function Questionnaire({ className, ...props }: React.ComponentProps<typeof Ques
);
}
function QuestionnaireProgress({ className, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Progress>) {
return (
<QuestionnairePrimitive.Progress
data-slot="questionnaire-progress"
className={cn("min-h-[1lh] w-fit min-w-[14ch] font-medium text-muted-foreground text-xs tabular-nums", className)}
{...props}
/>
);
}
function QuestionnaireItem({ className, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Item>) {
return (
<QuestionnairePrimitive.Item
@@ -48,19 +38,6 @@ function QuestionnaireTitle({ className, ...props }: React.ComponentProps<typeof
);
}
function QuestionnaireDescription({
className,
...props
}: React.ComponentProps<typeof QuestionnairePrimitive.Description>) {
return (
<QuestionnairePrimitive.Description
data-slot="questionnaire-description"
className={cn("text-pretty text-muted-foreground text-sm", className)}
{...props}
/>
);
}
function QuestionnaireChoices({ className, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Choices>) {
return (
<QuestionnairePrimitive.Choices
@@ -118,12 +95,6 @@ function QuestionnaireChoice({
);
}
function QuestionnaireChoiceDescription({ className, ...props }: React.ComponentProps<"span">) {
return (
<span data-slot="questionnaire-choice-description" className={cn("text-muted-foreground", className)} {...props} />
);
}
function QuestionnaireInput({ className, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Input>) {
return (
<div data-slot="questionnaire-input-wrapper" className="group/questionnaire-input relative w-full min-w-0">
@@ -163,81 +134,6 @@ function QuestionnaireActions({ className, ...props }: React.ComponentProps<"div
);
}
function QuestionnairePrevious({
children,
className,
size = "default",
variant = "outline",
...props
}: React.ComponentProps<typeof QuestionnairePrimitive.Previous> &
Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
return (
<QuestionnairePrimitive.Previous
data-slot="questionnaire-previous"
data-size={size}
data-variant={variant}
className={cn(
buttonVariants({ size, variant }),
"col-start-1 row-start-1 min-h-11 justify-self-start sm:min-h-0",
className,
)}
{...props}
>
{children ?? "Previous"}
</QuestionnairePrimitive.Previous>
);
}
function QuestionnaireSkip({
children,
className,
size = "default",
variant = "outline",
...props
}: React.ComponentProps<typeof QuestionnairePrimitive.Skip> &
Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
return (
<QuestionnairePrimitive.Skip
data-slot="questionnaire-skip"
data-size={size}
data-variant={variant}
className={cn(
buttonVariants({ size, variant }),
"col-start-2 row-start-1 min-h-11 justify-self-end sm:min-h-0",
className,
)}
{...props}
>
{children ?? "Skip"}
</QuestionnairePrimitive.Skip>
);
}
function QuestionnaireNext({
children,
className,
size = "default",
variant = "default",
...props
}: React.ComponentProps<typeof QuestionnairePrimitive.Next> &
Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
return (
<QuestionnairePrimitive.Next
data-slot="questionnaire-next"
data-size={size}
data-variant={variant}
className={cn(
buttonVariants({ size, variant }),
"col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0",
className,
)}
{...props}
>
{children ?? "Next"}
</QuestionnairePrimitive.Next>
);
}
function QuestionnaireSubmit({
children,
className,
@@ -267,16 +163,10 @@ export {
Questionnaire,
QuestionnaireActions,
QuestionnaireChoice,
QuestionnaireChoiceDescription,
QuestionnaireChoices,
QuestionnaireDescription,
QuestionnaireError,
QuestionnaireInput,
QuestionnaireItem,
QuestionnaireNext,
QuestionnairePrevious,
QuestionnaireProgress,
QuestionnaireSkip,
QuestionnaireSubmit,
QuestionnaireTitle,
};
-2
View File
@@ -41,8 +41,6 @@ export const rateLimitConfig = {
resumePassword: { maxRequests: 5, window: 10 * 60 * 1000 },
pdfExport: { maxRequests: 5, window: 60 * 1000 },
aiRequest: { maxRequests: 20, window: 60 * 1000 },
jobsSearch: { maxRequests: 30, window: 60 * 1000 },
jobsTestConnection: { maxRequests: 10, window: 60 * 1000 },
storageUpload: { maxRequests: 20, window: 60 * 1000 },
storageDelete: { maxRequests: 30, window: 60 * 1000 },
resumeMutations: { maxRequests: 300, window: 60 * 1000 },
-18
View File
@@ -730,9 +730,6 @@ importers:
babel-plugin-react-compiler:
specifier: ^1.0.0
version: 1.0.0
rimraf:
specifier: ^6.1.3
version: 6.1.3
typescript:
specifier: ^7.0.2
version: 7.0.2
@@ -7544,9 +7541,6 @@ packages:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
package-manager-detector@1.8.0:
resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==}
@@ -8056,11 +8050,6 @@ packages:
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
rimraf@6.1.3:
resolution: {integrity: sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==}
engines: {node: 20 || >=22}
hasBin: true
rolldown-plugin-dts@0.28.5:
resolution: {integrity: sha512-yYd3C9CeJwqjOc9X23m0Tyxcqic491uLZlfg51szT287S8zCCqLR2uoySoElgqy2CLn7PdXcEo1dlkBs4n1WHg==}
engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0}
@@ -14900,8 +14889,6 @@ snapshots:
p-try@2.2.0: {}
package-json-from-dist@1.0.1: {}
package-manager-detector@1.8.0: {}
pako@0.2.9: {}
@@ -15456,11 +15443,6 @@ snapshots:
reusify@1.1.0: {}
rimraf@6.1.3:
dependencies:
glob: 13.0.6
package-json-from-dist: 1.0.1
rolldown-plugin-dts@0.28.5(@typescript/native-preview@7.0.0-dev.20260707.2)(oxc-resolver@11.24.2)(rolldown@1.2.7)(typescript@7.0.2):
dependencies:
dts-resolver: 3.0.0(oxc-resolver@11.24.2)