diff --git a/.gitignore b/.gitignore index 167348b26..a3d9afaa5 100644 Binary files a/.gitignore and b/.gitignore differ diff --git a/AGENTS.md b/AGENTS.md index 0d0268cf8..392e1ecc1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,10 +22,10 @@ Workspace scripts are defined in [package.json](/package.json). ## Production Deployment Endpoints & Domains -- **Frontend Landing**: `https://urbackend.bitbros.in` -- **Dashboard App**: `https://app.urbackend.bitbros.in` -- **Dashboard API (Internal/Admin)**: `https://api.urbackend.bitbros.in` -- **Public API (SDK & User Auth)**: `https://api.ub.bitbros.in` +- **Frontend Landing**: `https://urbackend.in/` +- **Dashboard App**: `https://app.urbackend.in/` +- **Dashboard API (Internal/Admin)**: `https://platform-api.urbackend.in/` +- **Public API (SDK & User Auth)**: `https://api.urbackend.in/` ## Important project rules diff --git a/apps/dashboard-api/src/__tests__/project.controller.softDelete.test.js b/apps/dashboard-api/src/__tests__/project.controller.softDelete.test.js index 43e55f81c..788dd9758 100644 --- a/apps/dashboard-api/src/__tests__/project.controller.softDelete.test.js +++ b/apps/dashboard-api/src/__tests__/project.controller.softDelete.test.js @@ -34,7 +34,8 @@ const mongoose = require('mongoose'); function makeReq() { return { params: { projectId: 'proj_1', collectionName: 'posts', id: '507f1f77bcf86cd799439011' }, - user: { _id: 'user_1' } + user: { _id: 'user_1' }, + query: {} }; } diff --git a/apps/landing/astro.config.mjs b/apps/landing/astro.config.mjs index 2154b1493..8b3e84236 100644 --- a/apps/landing/astro.config.mjs +++ b/apps/landing/astro.config.mjs @@ -1,17 +1,22 @@ // @ts-check import { defineConfig } from 'astro/config'; +import mdx from '@astrojs/mdx'; import react from '@astrojs/react'; import sitemap from '@astrojs/sitemap'; import vercel from '@astrojs/vercel'; // https://astro.build/config export default defineConfig({ - site: 'https://urbackend.bitbros.in', + site: 'https://urbackend.in', + redirects: { + '/sitemap.xml': '/sitemap-index.xml', + }, integrations: [ react(), + mdx(), sitemap({ - filter: (page) => page === 'https://urbackend.bitbros.in/', + filter: (page) => !page.includes('/404'), }), ], adapter: vercel() diff --git a/apps/landing/package.json b/apps/landing/package.json index d2acb0382..823c42bf7 100644 --- a/apps/landing/package.json +++ b/apps/landing/package.json @@ -12,6 +12,7 @@ "astro": "astro" }, "dependencies": { + "@astrojs/mdx": "^4.x", "@astrojs/react": "^4.x", "@astrojs/sitemap": "^3.x", "@astrojs/vercel": "^9.0.0", diff --git a/apps/landing/public/badges/mintlify.svg b/apps/landing/public/badges/mintlify.svg new file mode 100644 index 000000000..514234094 --- /dev/null +++ b/apps/landing/public/badges/mintlify.svg @@ -0,0 +1 @@ +Mintlify \ No newline at end of file diff --git a/apps/landing/public/badges/mongodb.svg b/apps/landing/public/badges/mongodb.svg new file mode 100644 index 000000000..6a5554e5a --- /dev/null +++ b/apps/landing/public/badges/mongodb.svg @@ -0,0 +1 @@ +MongoDB \ No newline at end of file diff --git a/apps/landing/public/robots.txt b/apps/landing/public/robots.txt index 3b9797192..acfe8b564 100644 --- a/apps/landing/public/robots.txt +++ b/apps/landing/public/robots.txt @@ -1,4 +1,5 @@ User-agent: * Allow: / -Sitemap: https://urbackend.bitbros.in/sitemap.xml +Sitemap: https://urbackend.in/sitemap-index.xml +Sitemap: https://urbackend.in/sitemap-0.xml diff --git a/apps/landing/public/sitemap.xml b/apps/landing/public/sitemap.xml deleted file mode 100644 index 4af579212..000000000 --- a/apps/landing/public/sitemap.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - https://urbackend.bitbros.in/ - 2026-09-17 - weekly - 1.0 - - diff --git a/apps/landing/src/components/BlogCard.astro b/apps/landing/src/components/BlogCard.astro new file mode 100644 index 000000000..4c7a9091a --- /dev/null +++ b/apps/landing/src/components/BlogCard.astro @@ -0,0 +1,151 @@ +--- +import { ArrowRight, Calendar, User } from 'lucide-react'; + +interface Props { + slug: string; + title: string; + description: string; + date: Date | string; + author: string; + category: string; + tags?: string[]; +} + +const { slug, title, description, date, author, category, tags = [] } = Astro.props; + +const formattedDate = new Date(date).toLocaleDateString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + timeZone: 'UTC', +}); +--- + +
+ +
+ {category} + + + {formattedDate} + +
+ +

{title}

+

{description}

+ + +
+
+ + diff --git a/apps/landing/src/components/ChangelogTimeline.astro b/apps/landing/src/components/ChangelogTimeline.astro new file mode 100644 index 000000000..8a945b90e --- /dev/null +++ b/apps/landing/src/components/ChangelogTimeline.astro @@ -0,0 +1,347 @@ +--- +import { Tag, Sparkles, Wrench, Bug, ExternalLink } from 'lucide-react'; + +export interface ReleaseEntry { + title: string; + date: string; + version?: string; + summary?: string; + features?: string[]; + improvements?: string[]; + fixes?: string[]; + link?: string; +} + +interface Props { + releases: ReleaseEntry[]; +} + +const { releases } = Astro.props; +--- + +
+
+ + {releases.map((release) => ( +
+
+
+
+ +
+
+
+ {release.date} + {release.version && ( + + + {release.version} + + )} +
+

{release.title}

+ {release.summary &&

{release.summary}

} +
+ +
+ {release.features && release.features.length > 0 && ( +
+

+ New Features +

+
    + {release.features.map((item) => ( +
  • + + +
  • + ))} +
+
+ )} + + {release.improvements && release.improvements.length > 0 && ( +
+

+ Improvements +

+
    + {release.improvements.map((item) => ( +
  • + + +
  • + ))} +
+
+ )} + + {release.fixes && release.fixes.length > 0 && ( +
+

+ Bug Fixes +

+
    + {release.fixes.map((item) => ( +
  • + + +
  • + ))} +
+
+ )} +
+ + {release.link && ( + + )} +
+
+ ))} +
+ + diff --git a/apps/landing/src/components/ComparisonTable.astro b/apps/landing/src/components/ComparisonTable.astro new file mode 100644 index 000000000..ea63471e2 --- /dev/null +++ b/apps/landing/src/components/ComparisonTable.astro @@ -0,0 +1,233 @@ +--- +import { Check, X, Minus } from 'lucide-react'; + +interface ComparisonRow { + category: string; + feature: string; + urbackend: string | boolean; + competitor: string | boolean; + note?: string; +} + +interface Props { + competitor: string; + rows: ComparisonRow[]; +} + +const { competitor, rows } = Astro.props; + +// Group rows by category +const categories = Array.from(new Set(rows.map((r) => r.category))); +--- + +
+
+ + + + + + + + + + {categories.map((cat) => ( + <> + + + + {rows.filter((r) => r.category === cat).map((row) => ( + + + + + + ))} + + ))} + +
Feature +
+ urBackend + MongoDB Native +
+
+
+ {competitor} +
+
{cat}
+
{row.feature}
+ {row.note &&
{row.note}
} +
+ {typeof row.urbackend === 'boolean' ? ( + row.urbackend ? ( + + ) : ( + + ) + ) : ( + {row.urbackend} + )} + + {typeof row.competitor === 'boolean' ? ( + row.competitor ? ( + + ) : ( + + ) + ) : ( + {row.competitor} + )} +
+
+
+ + diff --git a/apps/landing/src/components/Footer.astro b/apps/landing/src/components/Footer.astro index d1669e31d..236474571 100644 --- a/apps/landing/src/components/Footer.astro +++ b/apps/landing/src/components/Footer.astro @@ -1,6 +1,6 @@ --- import { Github, ArrowRight } from 'lucide-react'; -const ADMIN_EMAIL = 'yashpouranik@gmail.com'; // Hardcoding since this is static site +const ADMIN_EMAIL = 'yash@urbackend.in'; // Official contact email ---