The Smart Calc hero
04Full Stack Web Application

The Smart Calc

Multilingual Financial Calculator Platform

A bilingual financial calculator platform with a secure admin CMS, multilingual blog system, and SEO-first architecture.

Financial PlatformFull StackSEOMultilingual
01 // Overview

About the Project

What it is

A multilingual financial calculator platform providing free financial tools alongside a CMS-driven educational blog.

Who it's for

Individuals, students, investors, and anyone needing quick financial calculations without creating an account.

Why it exists

To simplify everyday financial calculations while making educational financial content available in both English and Arabic.

02 // My Role

What I Built

Full Stack Development

Designed and implemented both frontend and backend architecture.

Calculator Engine

Built reusable financial calculation modules with TypeScript.

Internationalization

Implemented complete bilingual support including RTL layouts.

SEO

Implemented structured metadata, JSON-LD and multilingual SEO.

03 // Key Capabilities

What It Can Do

12 Financial Calculators

Admin Dashboard

Bilingual Blog

Password Reset

04 // Under the Hood

Engineering Deep Dive

Click any card to read the full technical detail.

05 // Engineering Decisions

Challenges & Trade-offs

The real decisions behind the architecture.

⚠ Challenge

How to handle financial arithmetic without floating-point errors in JavaScript

→ Decision

Replaced native JavaScript Number arithmetic with the decimal.js library across all 12 calculator modules. Every intermediate value in a multi-step calculation (e.g. monthly rate derivation inside loan amortization) is kept as a Decimal instance and only converted to a primitive string for display.

⇄ Trade-off

Adds a dependency and slightly more verbose code, but eliminates the class of bugs where 0.1 + 0.2 === 0.30000000000000004 — critical for a platform where users trust the numbers.

⚠ Challenge

How to serve bilingual content without a third-party translation API at runtime

→ Decision

Stored all UI strings and calculator labels in flat JSON message files per locale (en.json, ar.json) loaded at build time. Next.js middleware maps each incoming request to the correct locale and the message file is imported statically in Server Components.

⇄ Trade-off

Translations must be maintained manually in the JSON files — there is no auto-sync with a translation platform — but page load has zero network round-trip overhead for i18n.

⚠ Challenge

How to monetize a free calculator platform without degrading performance

→ Decision

Google AdSense ad units are loaded lazily via a dynamic import behind an IntersectionObserver. The ad script is deferred until the ad slot enters the viewport, so it never blocks the main thread during initial page load.

⇄ Trade-off

Ads appear slightly later than on platforms that load them eagerly, but Core Web Vitals scores (LCP, CLS) are not impacted by ad loading weight.

⚠ Challenge

Loan amortization schedules for long tenures (30-year mortgages) were generating tables with 360 rows, causing noticeable render lag on low-end devices.

→ Solution

Implemented virtual pagination on the amortization table: only the first 12 rows are rendered on mount, with a 'Load more' button that appends the next 12 rows. The full schedule is computed once and held in a ref, so pagination is pure DOM addition with no recomputation.

✓ Result

Initial render time dropped from ~400ms to under 50ms for a 30-year schedule while keeping the full data available without a round-trip.

⚠ Challenge

RTL layout required more than a CSS direction flip — form inputs, number formatting, and error message alignment all had to adapt to Arabic reading order.

→ Solution

Created a useLocale hook that exposes the current locale and a dir value. Components that need direction-aware styles consume dir and apply conditional class names. Number formatting uses Intl.NumberFormat with the locale string so Arabic numerals render correctly in ar locale.

✓ Result

The Arabic version of the site is a full RTL experience — inputs, labels, error states, and number outputs all respect Arabic reading order without any hardcoded LTR overrides.

06 // Architecture

System Design

Next.js App Router with locale-prefixed routes (/en, /ar) and a middleware that reads the Accept-Language header and redirects bare paths to the correct locale
Pure TypeScript calculator modules — each calculator is a pure function that accepts typed inputs and returns a typed result object; no shared state between calculators
Prisma ORM targeting MongoDB for the CMS blog system; the admin dashboard performs CRUD on articles through a set of Server Actions
JWT authentication stored in HTTP-only cookies; the admin middleware verifies the token on every request to /admin routes before rendering the page
Next.js generateMetadata and generateStaticParams used to pre-render all calculator pages and blog articles at build time for maximum SEO performance
07 // Performance

What Makes It Fast

Static Generation

all calculator and blog pages are pre-rendered at build time; zero server computation per visitor request

React Compiler

enabled to automatically memoize components, eliminating the need for manual useMemo and useCallback on calculator form components

Lazy Ad Loading

Google AdSense units are loaded behind an IntersectionObserver so the ad script never blocks the initial page render

Image Optimization

Next.js Image component serves AVIF/WebP with correct srcset and sizes; layout-shift from image loading is prevented with explicit width and height

08 // Security

Security Model

JWT Authentication with HTTP-only cookies

tokens are never exposed to client-side JavaScript

bcrypt password hashing with a cost factor of 12 applied to all admin account passwords

bcrypt password hashing with a cost factor of 12 applied to all admin account passwords

Admin middleware runs server-side on every /admin route before any page data is fetched or rendered

Admin middleware runs server-side on every /admin route before any page data is fetched or rendered

Rate limiting on the login endpoint prevents brute-force attacks on the admin account

Rate limiting on the login endpoint prevents brute-force attacks on the admin account

09 // Deployment

How It Ships

VPS — self-hosted on a Linux VPS; the Next.js server runs as a long-lived process managed by PM2
PM2 — process manager keeps the server alive across crashes, restarts on file change in development, and provides a startup script for server reboots
Nginx — reverse proxy sitting in front of the Next.js server, handling SSL termination, HTTP-to-HTTPS redirect, and static asset caching headers
10 // Gallery

Screenshots

Architecture Diagrams
11 // Resources

Links & Assets

🌐 Live Demo ↗
01 // HERO