From ed8fb0989d9b65498f94c3c4babc7b8809d72def Mon Sep 17 00:00:00 2001 From: Prashantkumar Khatri Date: Wed, 3 Jun 2026 16:56:23 +0530 Subject: [PATCH] refactor: remove entire web application directory and associated source files --- apps/web/.gitignore | 23 - apps/web/.npmrc | 1 - apps/web/README.md | 23 - apps/web/package.json | 26 -- apps/web/src/app.css | 206 --------- apps/web/src/app.d.ts | 13 - apps/web/src/app.html | 16 - apps/web/src/hooks.server.ts | 13 - apps/web/src/lib/apiClient.ts | 36 -- apps/web/src/lib/assets/favicon.svg | 1 - apps/web/src/lib/index.ts | 1 - apps/web/src/routes/+layout.svelte | 11 - apps/web/src/routes/+page.svelte | 214 --------- .../src/routes/devcard/[id]/+page.server.ts | 28 -- apps/web/src/routes/devcard/[id]/+page.svelte | 375 --------------- .../src/routes/u/[username]/+page.server.ts | 16 - apps/web/src/routes/u/[username]/+page.svelte | 437 ------------------ apps/web/static/robots.txt | 3 - apps/web/svelte.config.js | 30 -- apps/web/tsconfig.json | 20 - apps/web/vite.config.ts | 6 - 21 files changed, 1499 deletions(-) delete mode 100644 apps/web/.gitignore delete mode 100644 apps/web/.npmrc delete mode 100644 apps/web/README.md delete mode 100644 apps/web/package.json delete mode 100644 apps/web/src/app.css delete mode 100644 apps/web/src/app.d.ts delete mode 100644 apps/web/src/app.html delete mode 100644 apps/web/src/hooks.server.ts delete mode 100644 apps/web/src/lib/apiClient.ts delete mode 100644 apps/web/src/lib/assets/favicon.svg delete mode 100644 apps/web/src/lib/index.ts delete mode 100644 apps/web/src/routes/+layout.svelte delete mode 100644 apps/web/src/routes/+page.svelte delete mode 100644 apps/web/src/routes/devcard/[id]/+page.server.ts delete mode 100644 apps/web/src/routes/devcard/[id]/+page.svelte delete mode 100644 apps/web/src/routes/u/[username]/+page.server.ts delete mode 100644 apps/web/src/routes/u/[username]/+page.svelte delete mode 100644 apps/web/static/robots.txt delete mode 100644 apps/web/svelte.config.js delete mode 100644 apps/web/tsconfig.json delete mode 100644 apps/web/vite.config.ts diff --git a/apps/web/.gitignore b/apps/web/.gitignore deleted file mode 100644 index 3b462cb0..00000000 --- a/apps/web/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -node_modules - -# Output -.output -.vercel -.netlify -.wrangler -/.svelte-kit -/build - -# OS -.DS_Store -Thumbs.db - -# Env -.env -.env.* -!.env.example -!.env.test - -# Vite -vite.config.js.timestamp-* -vite.config.ts.timestamp-* diff --git a/apps/web/.npmrc b/apps/web/.npmrc deleted file mode 100644 index b6f27f13..00000000 --- a/apps/web/.npmrc +++ /dev/null @@ -1 +0,0 @@ -engine-strict=true diff --git a/apps/web/README.md b/apps/web/README.md deleted file mode 100644 index a6b2694e..00000000 --- a/apps/web/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# DevCard Web - -The web backup frontend for DevCard, built with [SvelteKit](https://kit.svelte.dev/). - -This app provides: -- The landing page for DevCard -- Public, browser-accessible profiles with view analytics -- Cross-platform analytics source tracking - -## Developing - -```bash -pnpm install -pnpm dev -``` - -## Building - -To create a production version of your app: - -```bash -pnpm build -``` diff --git a/apps/web/package.json b/apps/web/package.json deleted file mode 100644 index 3601215b..00000000 --- a/apps/web/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "@devcard/web", - "private": true, - "version": "0.0.1", - "type": "module", - "scripts": { - "dev": "vite dev --host", - "build": "vite build", - "preview": "vite preview", - "prepare": "svelte-kit sync || echo ''", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" - }, - "dependencies": { - "@devcard/shared": "workspace:*" - }, - "devDependencies": { - "@sveltejs/adapter-auto": "^7.0.0", - "@sveltejs/kit": "^2.50.2", - "@sveltejs/vite-plugin-svelte": "^6.2.4", - "svelte": "^5.51.0", - "svelte-check": "^4.4.2", - "typescript": "^5.9.3", - "vite": "^7.3.1" - } -} diff --git a/apps/web/src/app.css b/apps/web/src/app.css deleted file mode 100644 index 0f9e8bb0..00000000 --- a/apps/web/src/app.css +++ /dev/null @@ -1,206 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Outfit:wght@500;600;700;800;900&display=swap'); - -:root { - /* Primary Palette */ - --primary: #6366f1; - --primary-glow: rgba(99, 102, 241, 0.4); - --accent: #a855f7; - --accent-glow: rgba(168, 85, 247, 0.35); - - /* Backgrounds */ - --bg-primary: #ffffff; - --bg-secondary: #f8fafc; - --bg-page: #eef2ff; - --bg-glass: rgba(255, 255, 255, 0.38); - --bg-card: #ffffff; - - /* Text */ - --text-primary: #0f172a; - --text-secondary: #475569; - --text-muted: #64748b; - - /* Effects */ - --border: rgba(226, 232, 240, 0.9); - --border-glass: rgba(99, 102, 241, 0.25); - --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); - --shadow-md: 0 6px 18px -8px rgb(0 0 0 / 0.12), 0 4px 14px -12px rgb(0 0 0 / 0.08); - --shadow-lg: 0 12px 24px -10px rgb(0 0 0 / 0.15), 0 6px 12px -14px rgb(0 0 0 / 0.08); - --shadow-nav: 0 8px 32px -8px rgba(99, 102, 241, 0.18), 0 2px 8px 0 rgba(99, 102, 241, 0.08); - - --radius: 14px; - --radius-lg: 26px; - --radius-xl: 34px; - - --theme-transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1); -} - -html.dark { - --bg-primary: #020617; - --bg-secondary: #0f172a; - --bg-page: #050b18; - --bg-glass: rgba(15, 23, 42, 0.72); - --bg-card: #0f172a; - - --text-primary: #f8fafc; - --text-secondary: #cbd5e1; - --text-muted: #64748b; - - --border: rgba(30, 41, 59, 0.85); - --border-glass: rgba(255, 255, 255, 0.12); - --shadow-nav: 0 4px 24px -6px rgba(0, 0, 0, 0.45), 0 1px 4px 0 rgba(0, 0, 0, 0.25); -} - -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'Inter', sans-serif; - background: - radial-gradient(ellipse at 60% -10%, rgba(99, 102, 241, 0.28) 0%, transparent 55%), - radial-gradient(ellipse at -10% 80%, rgba(168, 85, 247, 0.18) 0%, transparent 45%), - radial-gradient(ellipse at 100% 60%, rgba(99, 102, 241, 0.12) 0%, transparent 40%), - var(--bg-page); - color: var(--text-primary); - transition: var(--theme-transition); - -webkit-font-smoothing: antialiased; - min-height: 100vh; - overflow-x: hidden; -} - -h1, h2, h3, h4, h5, h6 { - font-family: 'Outfit', sans-serif; - font-weight: 700; - line-height: 1.15; -} - -a { - color: inherit; - text-decoration: none; - transition: var(--theme-transition); -} - -button, -.btn-primary, -.btn-secondary { - transition: transform 0.24s ease, box-shadow 0.24s ease, background-color 0.24s ease, border-color 0.24s ease, color 0.24s ease; -} - -button { - font: inherit; -} - -.glass { - background: var(--bg-glass); - backdrop-filter: blur(18px); - -webkit-backdrop-filter: blur(18px); - border: 1px solid var(--border-glass); - box-shadow: var(--shadow-nav); -} - -.gradient-text { - background: linear-gradient(135deg, var(--primary), var(--accent)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.btn-primary { - display: inline-flex; - align-items: center; - justify-content: center; - background: linear-gradient(135deg, var(--primary), var(--accent)); - color: white; - padding: 0.95rem 1.85rem; - border-radius: calc(var(--radius) * 1.2); - font-weight: 700; - box-shadow: 0 18px 35px -18px rgba(99, 102, 241, 0.9); - border: none; - cursor: pointer; -} - -.btn-primary:hover { - transform: translateY(-2px); - box-shadow: 0 22px 40px -16px rgba(99, 102, 241, 0.9); -} - -.btn-primary:focus-visible { - outline: 3px solid rgba(99, 102, 241, 0.35); - outline-offset: 3px; -} - -.btn-secondary { - display: inline-flex; - align-items: center; - justify-content: center; - padding: 0.85rem 1.75rem; - border-radius: calc(var(--radius) * 1.2); - font-weight: 700; - border: 1px solid rgba(255, 255, 255, 0.14); - background: rgba(255, 255, 255, 0.08); - color: var(--text-primary); - cursor: pointer; -} - -.btn-secondary:hover { - background: rgba(255, 255, 255, 0.14); - border-color: rgba(99, 102, 241, 0.45); -} - -.btn-secondary:focus-visible { - outline: 3px solid rgba(99, 102, 241, 0.18); - outline-offset: 3px; -} - -/* ---------- Custom themed scrollbar (issue #151) ---------- */ - -/* Firefox */ -html { - scrollbar-width: thin; - scrollbar-color: var(--primary) var(--bg-secondary); -} - -/* WebKit (Chromium, Safari, Edge) */ -::-webkit-scrollbar { - width: 10px; - height: 10px; -} - -::-webkit-scrollbar-track { - background: var(--bg-secondary); - border-radius: 999px; -} - -::-webkit-scrollbar-thumb { - background: linear-gradient(135deg, var(--primary), var(--accent)); - border-radius: 999px; - border: 2px solid var(--bg-secondary); - background-clip: padding-box; - transition: background 0.2s ease, box-shadow 0.2s ease; -} - -::-webkit-scrollbar-thumb:hover { - background: linear-gradient(135deg, var(--accent), var(--primary)); - box-shadow: 0 0 8px var(--primary-glow); -} - -::-webkit-scrollbar-corner { - background: var(--bg-secondary); -} - -@media (prefers-reduced-motion: reduce) { - * { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - scroll-behavior: auto !important; - } -} - -/* Light mode btn-secondary fix */ -:root:not(.dark) .btn-secondary { - border-color: var(--border); - background: rgba(0, 0, 0, 0.04); -} \ No newline at end of file diff --git a/apps/web/src/app.d.ts b/apps/web/src/app.d.ts deleted file mode 100644 index da08e6da..00000000 --- a/apps/web/src/app.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -// See https://svelte.dev/docs/kit/types#app.d.ts -// for information about these interfaces -declare global { - namespace App { - // interface Error {} - // interface Locals {} - // interface PageData {} - // interface PageState {} - // interface Platform {} - } -} - -export {}; diff --git a/apps/web/src/app.html b/apps/web/src/app.html deleted file mode 100644 index 666257e4..00000000 --- a/apps/web/src/app.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - %sveltekit.head% - - -
%sveltekit.body%
- - diff --git a/apps/web/src/hooks.server.ts b/apps/web/src/hooks.server.ts deleted file mode 100644 index e17520ec..00000000 --- a/apps/web/src/hooks.server.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { Handle } from '@sveltejs/kit'; - -export const handle: Handle = async ({ event, resolve }) => { - const response = await resolve(event); - - // Security Headers (Note: CSP is handled in svelte.config.js) - response.headers.set('X-Content-Type-Options', 'nosniff'); - response.headers.set('Referrer-Policy', 'no-referrer'); - response.headers.set('X-Frame-Options', 'DENY'); - response.headers.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=()'); - - return response; -}; diff --git a/apps/web/src/lib/apiClient.ts b/apps/web/src/lib/apiClient.ts deleted file mode 100644 index dbaad43f..00000000 --- a/apps/web/src/lib/apiClient.ts +++ /dev/null @@ -1,36 +0,0 @@ -const API_BASE_URL = import.meta.env.PUBLIC_API_URL ?? 'http://localhost:3000'; - -type RequestOptions = { - method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; - body?: unknown; - token?: string | null; - onUnauthorized?: () => void; -}; - -export async function apiRequest( - endpoint: string, - { method = 'GET', body, token, onUnauthorized }: RequestOptions = {} -): Promise { - const headers: Record = { - 'Content-Type': 'application/json', - ...(token ? { Authorization: `Bearer ${token}` } : {}), - }; - - const response = await fetch(`${API_BASE_URL}${endpoint}`, { - method, - headers, - ...(body ? { body: JSON.stringify(body) } : {}), - }); - - if (response.status === 401 || response.status === 403) { - onUnauthorized?.(); - throw new Error('Unauthorized'); - } - - if (!response.ok) { - const error = await response.json().catch(() => ({})); - throw new Error((error as any)?.message ?? `Request failed: ${response.status}`); - } - - return response.json() as Promise; -} \ No newline at end of file diff --git a/apps/web/src/lib/assets/favicon.svg b/apps/web/src/lib/assets/favicon.svg deleted file mode 100644 index cc5dc66a..00000000 --- a/apps/web/src/lib/assets/favicon.svg +++ /dev/null @@ -1 +0,0 @@ -svelte-logo \ No newline at end of file diff --git a/apps/web/src/lib/index.ts b/apps/web/src/lib/index.ts deleted file mode 100644 index 856f2b6c..00000000 --- a/apps/web/src/lib/index.ts +++ /dev/null @@ -1 +0,0 @@ -// place files you want to import through the `$lib` alias in this folder. diff --git a/apps/web/src/routes/+layout.svelte b/apps/web/src/routes/+layout.svelte deleted file mode 100644 index ac6dd12f..00000000 --- a/apps/web/src/routes/+layout.svelte +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - -{@render children()} diff --git a/apps/web/src/routes/+page.svelte b/apps/web/src/routes/+page.svelte deleted file mode 100644 index efaa65e5..00000000 --- a/apps/web/src/routes/+page.svelte +++ /dev/null @@ -1,214 +0,0 @@ - \ No newline at end of file diff --git a/apps/web/src/routes/devcard/[id]/+page.server.ts b/apps/web/src/routes/devcard/[id]/+page.server.ts deleted file mode 100644 index a93fbc75..00000000 --- a/apps/web/src/routes/devcard/[id]/+page.server.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { error } from '@sveltejs/kit'; -import type { PageServerLoad } from './$types'; - -const API_BASE = process.env.BACKEND_URL || 'http://localhost:3000'; - -export const load: PageServerLoad = async ({ params, fetch }) => { - const { id } = params; - - try { - const res = await fetch(`${API_BASE}/api/u/card/${id}`); - - if (res.status === 404) { - throw error(404, 'Card not found'); - } - - if (!res.ok) { - throw error(500, 'Failed to load card'); - } - - const card = await res.json(); - return { card }; - } catch (error) { - if (error && typeof error === 'object' && 'status' in error) { - throw error; - } - throw error(500, 'Failed to connect to backend'); - } -}; diff --git a/apps/web/src/routes/devcard/[id]/+page.svelte b/apps/web/src/routes/devcard/[id]/+page.svelte deleted file mode 100644 index 7423f7ba..00000000 --- a/apps/web/src/routes/devcard/[id]/+page.svelte +++ /dev/null @@ -1,375 +0,0 @@ - - - - {card.title} | {card.owner.displayName} - - - -
-
- -
-
- -
-
-
- DevCard PRO -
- 📶 -
- -
-
- {#if card.owner.avatarUrl} - {card.owner.displayName} - {:else} -
- {card.owner.displayName.charAt(0).toUpperCase()} -
- {/if} -
-
-

{card.owner.displayName}

-

- {card.owner.role || 'Developer'}{card.owner.company ? ` @ ${card.owner.company}` : ''} -

- {#if card.owner.pronouns} -

{card.owner.pronouns}

- {/if} -
-
- -
-
- {#if card.owner.bio} -

{card.owner.bio}

- {/if} -
-
- PLATINUM -
-
-
- - -
-

Connections

-
- {#each card.links as link} - - {/each} -
-
- - -
-
- - diff --git a/apps/web/src/routes/u/[username]/+page.server.ts b/apps/web/src/routes/u/[username]/+page.server.ts deleted file mode 100644 index 042acadd..00000000 --- a/apps/web/src/routes/u/[username]/+page.server.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { PageServerLoad } from './$types'; - -const API_BASE = process.env.BACKEND_URL || 'http://localhost:3000'; - -export const load: PageServerLoad = async ({ params, fetch }) => { - try { - const res = await fetch(`${API_BASE}/api/u/${params.username}?source=web`); - if (!res.ok) { - return { profile: null, error: 'User not found' }; - } - const profile = await res.json(); - return { profile, error: null }; - } catch { - return { profile: null, error: 'Failed to load profile' }; - } -}; diff --git a/apps/web/src/routes/u/[username]/+page.svelte b/apps/web/src/routes/u/[username]/+page.svelte deleted file mode 100644 index 50cb4226..00000000 --- a/apps/web/src/routes/u/[username]/+page.svelte +++ /dev/null @@ -1,437 +0,0 @@ - - - - {#if profile} - {profile.displayName} | DevCard - - {:else} - User Not Found | DevCard - {/if} - - -
- -
- {#if error || !profile} -
-
😕
-

Profile not found

-

This DevCard has vanished into the digital void.

- Return Home -
- {:else} -
-
-
- {#if profile.avatarUrl} - {profile.displayName} - {:else} -
- {profile.displayName.charAt(0).toUpperCase()} -
- {/if} -
-
- -

{profile.displayName}

- {#if profile.role} -
- {profile.role}{profile.company ? ` @ ${profile.company}` : ''} -
- {/if} - - {#if profile.bio} -

{profile.bio}

- {/if} -
- - - -
-

Verified Developer Profile

-
⚡ DevCard
-
-
- -
-

Want a card like this?

-
- Create your DevCard ⚡ - -
- {#if copyMessage} -

- {copyMessage} -

- {/if} -
- {/if} -
- - diff --git a/apps/web/static/robots.txt b/apps/web/static/robots.txt deleted file mode 100644 index b6dd6670..00000000 --- a/apps/web/static/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# allow crawling everything by default -User-agent: * -Disallow: diff --git a/apps/web/svelte.config.js b/apps/web/svelte.config.js deleted file mode 100644 index 55c3bd2b..00000000 --- a/apps/web/svelte.config.js +++ /dev/null @@ -1,30 +0,0 @@ -import adapter from '@sveltejs/adapter-auto'; - -/** @type {import('@sveltejs/kit').Config} */ -const config = { - kit: { - // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. - // If your environment is not supported, or you settled on a specific environment, switch out the adapter. - // See https://svelte.dev/docs/kit/adapters for more information about adapters. - adapter: adapter(), - csp: { - mode: 'auto', - directives: { - 'default-src': ['self'], - 'script-src': ['self', 'unsafe-inline'], - 'style-src': ['self', 'unsafe-inline', 'https://fonts.googleapis.com'], - 'img-src': ['self', 'data:', 'https:'], - 'connect-src': ['self'], - 'font-src': ['self', 'data:', 'https:', 'https://fonts.gstatic.com'], - 'object-src': ['none'], - 'base-uri': ['self'], - 'frame-ancestors': ['none'] - } - } - }, - vitePlugin: { - dynamicCompileOptions: ({ filename }) => ({ runes: !filename.includes('node_modules') }) - } -}; - -export default config; diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json deleted file mode 100644 index 2c2ed3c4..00000000 --- a/apps/web/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./.svelte-kit/tsconfig.json", - "compilerOptions": { - "rewriteRelativeImportExtensions": true, - "allowJs": true, - "checkJs": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "sourceMap": true, - "strict": true, - "moduleResolution": "bundler" - } - // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias - // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files - // - // To make changes to top-level options such as include and exclude, we recommend extending - // the generated config; see https://svelte.dev/docs/kit/configuration#typescript -} diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts deleted file mode 100644 index bbf8c7da..00000000 --- a/apps/web/vite.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { sveltekit } from '@sveltejs/kit/vite'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - plugins: [sveltekit()] -});