Kaium Al Limon
Available
About
Skills
Impact
Projects
GitHub
Activities
Achievements
Let's Talk
All Projects
Web Project

Viae

A full-featured resume builder that combines a structured section-by-section editor with multiple layout templates, real-time ATS readability scoring, and high-fidelity PDF export — all in one cohesive application.

Source Code
Stars
0
Forks
0
Open Issues
0
Watchers
0

Languages

4Languages
  • TypeScript99%
  • CSS1%
  • PLpgSQL0%
  • JavaScript0%

Repository

Default Branch
master
Primary Language
TypeScript
Created
Jul 29, 2026
License
—
Size
990 KB
View Repository

Contributors

kaiumallimon
kaiumallimon
36 commits
+24,556
-5,978
staywithabdullah
staywithabdullah
1 commits
+1
-1

README

README.mdView on GitHub

Viae is a full-featured resume builder that combines a structured section-by-section editor with multiple layout templates, real-time ATS readability scoring, and high-fidelity PDF export — all in one cohesive application.

It is built with Next.js 16 (App Router, React 19), uses Supabase for authentication and persistence, renders PDFs client-side with @react-pdf/renderer, and ships four distinct templates.


Templates

Viae ships four templates, each with its own typography, layout strategy, and visual character. All templates share the same content model — switching between them preserves every field, bullet point, and date range.

TemplateLayoutTypefaceCharacter
ClassicSingle column, gradient header barHelvetica / systemFamiliar, clean, expected. A traditional timeline format with a blue-to-indigo header, section dividers, and a clear information hierarchy.
ModernTwo column, dark sidebarHelvetica / systemAsymmetric layout with a dark left sidebar housing contact info and grouped skills, while the main column carries experience, education, and supporting sections. High contrast.
CompactDense single column, thin accent barHelvetica / systemMaximizes content per page. A slim top accent bar anchors the layout; contact info sits inline with the name header. Tight spacing, condensed typography, minimal decoration.
ElegantCentered single column, serifTimes-Roman / GeorgiaRefined and traditional. A decorative divider beneath the centered name header sets the tone. Descriptions and institution names are set in italics. Longer leading and wider margins give the page room to breathe.

Each template exists as a self-contained plugin with three render surfaces — a live Preview component (React), a PDFDocument component (@react-pdf/renderer), and a Thumbnail for the template picker — registered in a central registry. This means adding a fifth template requires only dropping in a new folder and one line in the registry.


ATS Scoring Engine

The scoring engine evaluates resumes across seven dimensions, each weighted by its impact on automated application tracking system readability:

CategoryPointsWhat it measures
Contact Information15Presence and completeness of name, phone, email, LinkedIn, GitHub, and portfolio links
Section Completeness20Whether all eight content sections (Overview, Experience, Skills, Projects, Education, Activities, Achievements, References) are populated
Experience Quality20Number of entries, bullet points per entry, date range completeness, and measurable metrics (percentages, dollar amounts, numerical results)
Education Detail10Course name, institution, and date range presence
Skills Coverage10Skill groups populated; multiple groups scored higher for keyword density
Bullet Strength15Action verb detection ("achieved", "developed", "implemented", "led", "designed"), bullet length (50+ characters preferred), and quantified outcomes
Formatting & Consistency10Consistent date formatting and overall section count (6+ sections filled scores higher)

Total: 100 points. A letter grade is assigned: A (90+), B (80+), C (70+), D (60+), F (below 60).

The score is computed in real-time via a pure function (computeResumeScore) that walks the full ResumeData object. It uses no external API calls — the analysis happens entirely client-side. Results are displayed in a ScorePanel with a circular donut gauge, per-category progress bars, and specific improvement tips per category (e.g. "Add quantified metrics to your experience bullet points" when bullet points lack numbers).

The score is persisted as a JSONB column on the resumes table and updated each time the resume is saved.


Editor

The editor is built as a single-page form divided into nine collapsible sections. Each section maps to a distinct interface in the ResumeData type and is rendered by its own component within components/resume-builder/sections/.

  • Personal Section — Full name (required), designation, phone, email. GitHub, LinkedIn, and portfolio URL fields each have an associated display-text input (e.g. show a custom handle instead of the full URL). The resume title field is marked with a red asterisk to signal it's required for the save button to activate.
  • Overview — A single textarea for a professional summary or objective paragraph.
  • Experience — Repeatable cards. Each card has designation, company, employment status (badge), date range (plain text inputs with format hints like "e.g. June 2025"), and a dynamic list of bullet points. Bullet points have add/remove controls and can be reordered.
  • Skills — Grouped skill lists. Each group has a title and a comma-separated skills textarea. Groups can be added or removed.
  • Projects — Repeatable cards with title, status badge, bullet points, live URL, and a tools/technologies field.
  • Education — Repeatable cards with course, institution, date range, and result/grade.
  • Activities — Repeatable cards with title, organization, date range (using startDate/endDate), and description.
  • Achievements — Repeatable cards with a result heading and description body (rendered italic in PDF output).
  • References — Repeatable cards with name, designation, company, phone, and email.

All sections use a shared set of primitive components (FormField, RepeatableCard, BulletPointList, SectionHeader, SectionDivider) that enforce consistent spacing, label styling, and field background colour across the entire form. Input fields use a soft grey background (--field-background: #f1f5f9) to visually distinguish editable areas from static labels.

Autosave does not exist. Saving is manual only — the "Save Draft" button in the action bar persists the current state to Supabase. This avoids unexpected writes and keeps the user in control.


Preview and PDF

The preview page uses a two-column layout on desktop: the rendered template on the left and the ATS ScorePanel on the right. On mobile, the ScorePanel stacks below the preview card.

Preview flow starts with a template selection step (even when changing templates from an existing resume), which persists the new template_id to the database before redirecting. The preview renders the selected template's Preview component with the current ResumeData — the same React component tree used for live editing previews.

PDF generation uses @react-pdf/renderer to produce a .pdf blob client-side. Each template has a corresponding PDFDocument component that mirrors the layout and typography of its preview counterpart. The PDF document is wrapped in a shared ResumePDFDocument layer that injects fonts, applies global styles, and dispatches to the correct template. If PDF rendering fails, the print fallback uses window.print().

Key PDF details:

  • Classic PDF header has paddingHorizontal: 40 to align with body text
  • Section subtitle styles have marginTop: 3, marginBottom: 3 for consistent vertical rhythm
  • Body text light style uses marginTop: 2, marginBottom: 2
  • Skill rows use marginBottom: 5
  • Achievement descriptions use an italic achievementDesc style

Dashboard and Workspace

The dashboard is the user's home base. It lists all saved resumes with:

  • Resume title or fallback chain (resume.name || resume.data.title || resume.data.fullName || 'Untitled Resume')
  • Completion progress bar computed from the number of filled sections
  • ATS grade badge (A–F) displayed alongside the progress percentage
  • Last edited timestamp
  • Preview button — enabled only when full name, designation, and at least one contact field (phone or email) are present; greyed out otherwise
  • Delete with confirmation dialog

The sidebar shows the five most recently edited resumes, refreshed on resume-saved and resume-deleted custom events and on window focus.

Every dashboard page uses a sticky header (py-[18px], bg-sidebar/70, backdrop-blur-md) and shared DashboardBreadcrumbs with the Home lucide icon and / separator.


Architecture

app/
├── (auth)/               # Auth callback routes
├── auth/                  # Login page
├── dashboard/
│   ├── page.tsx           # Workspace — resume list, create button
│   ├── new/
│   │   ├── page.tsx       # New resume editor
│   │   ├── select/page.tsx  # Template picker
│   │   └── preview/page.tsx # Preview for unsaved resumes
│   ├── edit/[id]/page.tsx # Edit existing resume
│   ├── preview/[id]/page.tsx # Preview saved resume
│   ├── resumes/page.tsx   # Full resume list view
│   └── account/page.tsx   # Account settings
├── layout.tsx             # Root layout — SupabaseProvider, ThemeProvider, Toaster
├── page.tsx               # Landing / marketing page
└── globals.css            # Design tokens, CSS variables, Tailwind layers

components/
├── resume-builder/
│   ├── ResumeBuilder.tsx             # Editor orchestrator
│   ├── ResumeBuilderProvider.tsx     # Context provider
│   ├── sections/                     # PersonalSection, OverviewSection, ExperienceSection, …
│   └── common/                       # FormField, RepeatableCard, BulletPointList, ActionBar, SectionHeader
├── resume-score/
│   ├── ScorePanel.tsx                # Full score breakdown panel
│   └── ScoreGauge.tsx               # Circular donut gauge
├── resume-pdf.tsx                    # PDF document wrapper (dispatches to template PDF)
├── frosted-header.tsx                # Sticky glass-morphism header
├── dashboard-breadcrumbs.tsx          # Breadcrumb navigation component
└── dashboard-sidebar.tsx             # Sidebar with recents and grade badges

templates/
├── types.ts              # Template interface (id, name, description, Preview, PDFDocument, Thumbnail)
├── registry.ts           # Template registration and lookup
├── classic/              # Classic template
├── modern/               # Modern template
├── compact/              # Compact template
└── elegant/              # Elegant template

hooks/
├── use-resume-builder.ts # Core builder hook — state, field updates, save, import/export
├── use-resume-score.ts   # ATS scoring pure function
├── use-resumes.ts        # Resume list fetching and deletion
└── use-resume-progress.ts # Completion percentage calculation

types/
├── resume.ts             # ResumeData and all section interfaces
├── helpers.ts            # defaultData(), empty*(), migrateItem(), loadSaved()
└── score.ts              # ResumeScore, ScoreCategory, gradeFromScore()

supabase/migrations/      # Database migrations

Tech Stack

CategoryChoice
FrameworkNext.js 16 (App Router, React 19.2)
AuthenticationSupabase SSR (@supabase/ssr)
DatabaseSupabase PostgreSQL with JSONB for resume data
StylingTailwind CSS v4 (PostCSS plugin), dark mode via class strategy
UI PrimitivesHeroUI (@heroui/react)
PDF Generation@react-pdf/renderer v4
IconsLucide React
NotificationsSonner (<Toaster position="bottom-right" richColors />)
TypographyBricolage Grotesque (variable) + Inter (system)
LanguageTypeScript throughout
Package Managernpm

Polishing Details

  • Fallback title chain — The dashboard and breadcrumbs display resume.name || resume.data.title || resume.data.fullName || 'Untitled Resume', so a resume always has a name even before the user types one.
  • Context-aware back button — On preview pages, ?from=editor shows "Back to Editor"; without the param, it shows "Back to Dashboard".
  • Clickable contact URLs — In preview and PDF output, phone numbers get tel:, emails get mailto:, and URLs get https:// normalization via a toUrl() helper.
  • Soft field backgrounds — Input backgrounds are --field-background: #f1f5f9 in light mode, a subtle visual cue that distinguishes editable fields from static labels.
  • Breadcrumb separator — Uses plain / text instead of a HeroUI Breadcrumbs component, avoiding cloneElement className override issues.
  • Save notifications — Sonner toasts appear on successful saves.
  • Template thumbnails — The template picker shows a visual Thumbnail component for each template, not just text labels.
  • Grade badges — The sidebar and dashboard cards show A–F grade badges derived from the persisted score.
Kaium Al Limon

Full-Stack Mobile & Web Software Engineer building cross-platform Flutter applications, modern Next.js platforms, and scalable backends with clean architecture and production-ready code.

Available for workDhaka, Bangladesh
Flutter · Next.js · TypeScript · FastAPI · PostgreSQL

Navigation

AboutSkillsImpactProjectsGitHubActivitiesAchievementsContact

Tools Hub

GitHub UnwrappedUIU Exam RoutineUIU CGPA Calculator

Live Telemetry

@kaiumallimon

© 2026 Kaium Al Limon. All rights reserved.

kalimon291@gmail.com|