mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-10-03 10:13:47 +10:00
refactor: remove unused UI and runtime scaffolding
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
import z from "zod";
|
||||
|
||||
export const apiKeyDialogSchemas = [z.object({ type: z.literal("api-key.create"), data: z.undefined() })] as const;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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"];
|
||||
|
||||
@@ -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,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 };
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,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,
|
||||
};
|
||||
|
||||
@@ -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 },
|
||||
|
||||
Generated
-18
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user