RiDocs PDF Atelier is a browser-based PDF workspace built with React, Vite,
and shadcn UI. The first milestone focuses on merging multiple PDFs into one downloadable file, showing visual previews, and reordering the merge queue with drag and drop.
- React 19 + Vite 8 + TypeScript 6
- Clerk authentication
- Convex client wiring
- TanStack Query provider setup
- Global modal host for reusable confirmation flows
pdf-libfor client-side PDF merge and exportreact-pdffor PDF preview rendering@dnd-kit/reactfor full-card queue reordering- Editorial workshop theme tokens in
src/index.css
- Install dependencies:
bun install- Create your local environment file from
.env.example.
Required frontend env keys:
VITE_CLERK_PUBLISHABLE_KEY: Clerk publishable key from the Clerk dashboardVITE_CONVEX_URL: Convex client URL for the current deploymentVITE_CONVEX_SITE_URL: Public site URL used for auth/callback configuration
Optional local workflow key:
CONVEX_DEPLOYMENT: helpful for Convex local tooling such asnpx convex dev
- Verify the project:
bun run check- Build the production bundle when needed:
bun run buildbun run lint
bun run lint:fix
bun run typecheck
bun run format
bun run format:check
bun run checkbun run check is non-mutating. It runs linting, typechecking, and Prettier in
check mode.
/: redirect to/merge/merge: public PDF merge workspace
- Keep
/as the redirect/root entry insrc/pages/Root.tsx. - Put authenticated routes under
src/pages/authenticated/.... - Put unauthenticated routes under
src/pages/unauthenticated/.... - Mirror nested route segments with kebab-case folders.
- Name page files in PascalCase.
Examples:
/merge→src/pages/unauthenticated/merge/Merge.tsx/delete-pages→src/pages/unauthenticated/delete-pages/DeletePages.tsx/workspace-settings→src/pages/unauthenticated/workspace-settings/WorkspaceSettings.tsx
- Route-scoped hooks should live in matching folders like
src/hooks/merge/use-pdf-merge-workspace.ts. - Route-scoped types should live in matching folders like
src/types/merge/merge.types.ts. - Shared modal components should live under
src/components/modals/.... - Register global modal entries in
src/context/ModalProvider.tsx.
- Prefer direct imports from the concrete module path, for example
@/hooks/merge/use-pdf-merge-workspaceor@/components/ui/button. - Keep root barrel files only for intentionally shared public entry points.
- When adding new files, update a root barrel only if that module is meant to be a shared template-level export.
src/context/ConvexClerkProvider.tsxis the canonical Convex + Clerk wrapper.src/main.tsxshould compose app-level providers using that wrapper instead of duplicating the Convex provider setup inline.