mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-07 03:24:53 +10:00
b404dbd42a
* feat(applications): job application tracker with AI copilot Add an Applications module at /dashboard/applications: pipeline board (dnd-kit), table view with bulk actions, Insights (fit tiles, funnel, sources, shareable funnel-flow SVG), campaigns, tags, CSV import, and Add/Edit/Detail slide-overs. Each application links a live Reactive Resume. AI "Application Copilot" (applications.ai.*): job-posting autofill, resume↔job match score (fit ring), resume tailoring, and cover-letter / follow-up drafting — via the user's configured provider. Board cards + table rows get context menus (edit / move / archive / delete). Charts are CSS/SVG (no new chart dep); adds a UI Checkbox. Also includes local TanStack devtools setup and toolchain bumps. Claude-Session: https://claude.ai/code/session_01TEeRHnEayw2MFCShFRyL5f * feat(applications): close follow-up gaps + squash migrations Finish the deferred/open items on the applications tracker: - Cover-letter upload re-enabled. Fix the storage blocker by deriving the key extension from content type (buildFileKey/EXTENSION_BY_CONTENT_TYPE) instead of hardcoding .jpeg, so PDFs serve correctly and non-JPEG image avatars keep working under FLAG_DISABLE_IMAGE_PROCESSING. Add coverLetterUrl/coverLetterName columns + Documents-section upload/remove. - Contacts editor in the detail sheet (add/edit/remove, keyed per app). - Board caps rendered cards per column (COLUMN_PAGE_SIZE=50 + "Show more"). - Extract new Lingui messages across locales. - Guard coverLetterUrl to http(s)/relative at the API boundary. Squash the five branch-only application-table migrations (create -> +tags -> +cover-letter -> drop -> re-add) into a single clean CREATE TABLE via drizzle-kit generate. Claude-Session: https://claude.ai/code/session_01TEeRHnEayw2MFCShFRyL5f * chore: update dependencies * fix(web): address React Doctor findings — compiler, purity, query, component structure prefer-module-scope-pure-function: hoist buildSubtitle, getDecimalPlaces, handleLocaleChange, onLocaleChange, stop, listContent/groupedListContent to module scope so they aren't rebuilt on every render. react-compiler-todo (??=): rewrite draft.metadata.styleRules ??= [] to the non-assignment form to unblock auto-memoization. set-state-in-effect: derive updatedAtLabel at render time instead of syncing it through useState + useEffect. query-destructure-result: destructure useQuery results at call site in resume-analysis and resume-thumbnail to follow TanStack Query v5 convention. only-export-components: extract non-component exports to sibling .ts files so Fast Refresh can preserve component state: - getNextWeights → typography/get-next-weights.ts - detectJsonImportType + ImportType → dialogs/resume/import.utils.ts - getLocaleOptions → features/locale/locale-options.tsx - preview helpers + DEFAULT_PDF_PAGE_SIZE → preview.shared.utils.ts - resolveHighlightToolbarState + defaultHighlightColor → rich-input.utils.ts - computeDelta + getSparklinePoints → statistics.utils.ts no-multi-comp: split multi-component files into focused companions: - ResumePane + ToolbarButton → routes/agent/-components/resume-pane.tsx - DesktopBuilderShell → builder/$resumeId/-components/desktop-builder-shell.tsx - MobileBuilderShell + helpers → builder/$resumeId/-components/mobile-builder-shell.tsx - setBuilderLayout/getBuilderLayout moved to -store/sidebar.ts fix(tests): add Resume type import to section-builder mocks and cast partial mock data as unknown as Resume to satisfy stricter type checking; fix noExplicitAny Biome errors in the same mocks. * feat(applications): improve performance * chore: fix knip issues * perf(builder): halve per-keystroke render cost Section-form fields called `form.handleSubmit()` on every keystroke, which re-validated the whole form and toggled submit state — firing the render cascade twice per character (~6809 renders/keystroke, FPS dropping to 9). Persist via a form-level `listeners.onChange` instead and drop the per-field `handleSubmit()` (basics, custom-fields, design). Narrow header/dock resume subscriptions to metadata slices so they no longer re-render on content edits. Cuts renders 6809 -> 3403 per keystroke (50%), 0 frame drops. Save, preview, and design controls verified working; 449/449 web tests pass. * perf(home): eliminate hero CLS from unreserved video box The hero <section> is `flex items-center` (shrink-to-fit), so the video wrapper's width depended on the video's intrinsic size, which only resolves after the media loads. aspect-ratio couldn't reserve height without a definite width, so the video grew from ~190px to ~563px after first paint and shoved the centered hero text down ~373px (CLS ~0.095). Give the wrapper a definite width (w-full + mx-auto on the CometCard) and set an explicit aspect ratio + width/height on the video so its box is reserved before load. CLS 0.095 -> 0; hero stays visually centered at max-w-4xl. * docs: add application tracker guides * chore(db): squash application migrations * fix(email): import React in auth template for server-side rendering compatibility * chore(release): v5.2.1 * Refactor resume rendering and builder workflows * fix: address application tracker review findings
113 lines
3.8 KiB
JSON
113 lines
3.8 KiB
JSON
{
|
|
"name": "web",
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"private": true,
|
|
"scripts": {
|
|
"build": "rimraf dist && vite build",
|
|
"dev": "vite dev",
|
|
"serve": "vite preview",
|
|
"start": "vite preview",
|
|
"typecheck": "tsgo --noEmit",
|
|
"test": "vitest run --passWithNoTests",
|
|
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
"test:ci": "vitest run --coverage --reporter=default --reporter=github-actions --reporter=json --reporter=junit --outputFile.json=reports/vitest-results.json --outputFile.junit=reports/vitest-junit.xml --passWithNoTests",
|
|
"test:agent": "vitest run --reporter=agent --reporter=json --outputFile.json=reports/vitest-results.json --passWithNoTests",
|
|
"lingui:extract": "lingui extract --clean --overwrite"
|
|
},
|
|
"dependencies": {
|
|
"@ai-sdk/react": "^4.0.16",
|
|
"@base-ui/react": "^1.6.0",
|
|
"@better-auth/api-key": "^1.6.23",
|
|
"@better-auth/infra": "^0.3.4",
|
|
"@better-auth/oauth-provider": "^1.6.23",
|
|
"@better-auth/passkey": "^1.6.23",
|
|
"@dnd-kit/core": "^6.3.1",
|
|
"@dnd-kit/sortable": "^10.0.0",
|
|
"@dnd-kit/utilities": "^3.2.2",
|
|
"@lingui/core": "^6.4.0",
|
|
"@lingui/react": "^6.4.0",
|
|
"@orpc/client": "^1.14.6",
|
|
"@orpc/server": "^1.14.6",
|
|
"@orpc/tanstack-query": "^1.14.6",
|
|
"@phosphor-icons/react": "^2.1.10",
|
|
"@react-pdf/renderer": "^4.5.1",
|
|
"@reactive-resume/ai": "workspace:*",
|
|
"@reactive-resume/api": "workspace:*",
|
|
"@reactive-resume/auth": "workspace:*",
|
|
"@reactive-resume/docx": "workspace:*",
|
|
"@reactive-resume/fonts": "workspace:*",
|
|
"@reactive-resume/import": "workspace:*",
|
|
"@reactive-resume/pdf": "workspace:*",
|
|
"@reactive-resume/resume": "workspace:*",
|
|
"@reactive-resume/schema": "workspace:*",
|
|
"@reactive-resume/ui": "workspace:*",
|
|
"@reactive-resume/utils": "workspace:*",
|
|
"@tailwindcss/vite": "^4.3.2",
|
|
"@tanstack/react-form": "^1.33.0",
|
|
"@tanstack/react-hotkeys": "^0.10.0",
|
|
"@tanstack/react-query": "^5.101.2",
|
|
"@tanstack/react-router": "^1.170.17",
|
|
"@tiptap/extension-color": "^3.27.1",
|
|
"@tiptap/extension-highlight": "^3.27.1",
|
|
"@tiptap/extension-text-align": "^3.27.1",
|
|
"@tiptap/extension-text-style": "^3.27.1",
|
|
"@tiptap/pm": "^3.27.1",
|
|
"@tiptap/react": "^3.27.1",
|
|
"@tiptap/starter-kit": "^3.27.1",
|
|
"@types/js-cookie": "^3.0.6",
|
|
"@uiw/color-convert": "^2.10.3",
|
|
"@uiw/react-color-colorful": "^2.10.3",
|
|
"ai": "^7.0.15",
|
|
"better-auth": "1.6.23",
|
|
"cmdk": "^1.1.1",
|
|
"drizzle-orm": "1.0.0-rc.4",
|
|
"es-toolkit": "^1.49.0",
|
|
"fuse.js": "^7.4.2",
|
|
"immer": "^11.1.11",
|
|
"js-cookie": "^3.0.8",
|
|
"motion": "^12.42.2",
|
|
"pdfjs-dist": "6.1.200",
|
|
"pg": "^8.22.0",
|
|
"qrcode.react": "^4.2.0",
|
|
"react": "^19.2.7",
|
|
"react-dom": "^19.2.7",
|
|
"react-easy-crop": "^6.1.0",
|
|
"react-markdown": "^10.1.0",
|
|
"react-resizable-panels": "^4.12.1",
|
|
"react-window": "^2.2.7",
|
|
"react-zoom-pan-pinch": "^4.0.3",
|
|
"remark-gfm": "^4.0.1",
|
|
"sonner": "^2.0.7",
|
|
"ts-pattern": "^5.9.0",
|
|
"usehooks-ts": "^3.1.1",
|
|
"zod": "^4.4.3",
|
|
"zustand": "^5.0.14"
|
|
},
|
|
"devDependencies": {
|
|
"@babel/core": "^8.0.1",
|
|
"@lingui/babel-plugin-lingui-macro": "^6.4.0",
|
|
"@lingui/cli": "^6.4.0",
|
|
"@lingui/format-po": "^6.4.0",
|
|
"@lingui/vite-plugin": "^6.4.0",
|
|
"@reactive-resume/config": "workspace:*",
|
|
"@rolldown/plugin-babel": "^0.2.3",
|
|
"@tanstack/devtools-vite": "^0.8.1",
|
|
"@tanstack/react-devtools": "^0.10.8",
|
|
"@tanstack/react-query-devtools": "^5.101.2",
|
|
"@tanstack/react-router-devtools": "^1.167.0",
|
|
"@tanstack/router-plugin": "^1.168.19",
|
|
"@types/babel__core": "^7.20.5",
|
|
"@types/pg": "^8.20.0",
|
|
"@types/react": "^19.2.17",
|
|
"@types/react-dom": "^19.2.3",
|
|
"@typescript/native-preview": "7.0.0-dev.20260705.1",
|
|
"@vitejs/plugin-react": "^6.0.3",
|
|
"babel-plugin-macros": "^3.1.0",
|
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
"rimraf": "^6.1.3",
|
|
"typescript": "^6.0.3",
|
|
"vite": "^8.1.3"
|
|
}
|
|
}
|