From 591ac14ffce8b67957a25598fddf1b6179d4db8d Mon Sep 17 00:00:00 2001 From: jyswee Date: Thu, 23 Jul 2026 22:15:26 +0000 Subject: [PATCH] Seed: developer-tools template (15 files) --- src/pages/Changelog.tsx | 177 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 src/pages/Changelog.tsx diff --git a/src/pages/Changelog.tsx b/src/pages/Changelog.tsx new file mode 100644 index 0000000..2c99fe9 --- /dev/null +++ b/src/pages/Changelog.tsx @@ -0,0 +1,177 @@ +import { useState } from "react"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Rocket, Bug, AlertTriangle, TrendingUp, Mail } from "lucide-react"; +import { toast } from "sonner"; +import Header from "@/components/Header"; +import Footer from "@/components/Footer"; + +type ChangeType = "feature" | "fix" | "breaking" | "improvement"; + +interface Release { + version: string; + date: string; + title: string; + description: string; + changes: ChangeType[]; +} + +const releases: Release[] = [ + { + version: "2.4.0", + date: "Apr 2, 2024", + title: "Edge Functions & Global Deployments", + description: "Deploy serverless functions to 30+ edge regions with automatic geo-routing. Includes new SDK methods for managing edge deployments and improved cold start times.", + changes: ["feature", "improvement"], + }, + { + version: "2.3.1", + date: "Mar 25, 2024", + title: "Fix: Webhook Retry Logic", + description: "Fixed an issue where webhook retries could fire duplicate events. Improved idempotency key handling and added exponential backoff.", + changes: ["fix"], + }, + { + version: "2.3.0", + date: "Mar 18, 2024", + title: "v2 Authentication API", + description: "New authentication API with support for OAuth 2.0, API key scopes, and token rotation. Breaking: v1 auth endpoints deprecated and will be removed in v3.", + changes: ["feature", "breaking"], + }, + { + version: "2.2.2", + date: "Mar 5, 2024", + title: "Dashboard Performance & Bug Fixes", + description: "Reduced dashboard load time by 40%. Fixed pagination bug on project listing and resolved timezone display issues in analytics.", + changes: ["fix", "improvement"], + }, + { + version: "2.2.0", + date: "Feb 20, 2024", + title: "Real-Time Logs & Streaming", + description: "Stream deployment logs in real time via the CLI or dashboard. New log filtering, search, and export capabilities with structured JSON output.", + changes: ["feature", "improvement"], + }, +]; + +const typeConfig: Record = { + feature: { label: "Feature", color: "bg-emerald-500/10 text-emerald-400 border-emerald-500/20", icon: Rocket }, + fix: { label: "Fix", color: "bg-sky-500/10 text-sky-400 border-sky-500/20", icon: Bug }, + breaking: { label: "Breaking", color: "bg-red-500/10 text-red-400 border-red-500/20", icon: AlertTriangle }, + improvement: { label: "Improvement", color: "bg-amber-500/10 text-amber-400 border-amber-500/20", icon: TrendingUp }, +}; + +const filterOptions: { label: string; value: string }[] = [ + { label: "All", value: "all" }, + { label: "Features", value: "feature" }, + { label: "Fixes", value: "fix" }, + { label: "Breaking", value: "breaking" }, +]; + +export default function ChangelogPage() { + const [filter, setFilter] = useState("all"); + const [email, setEmail] = useState(""); + + const filtered = filter === "all" + ? releases + : releases.filter((r) => r.changes.includes(filter as ChangeType)); + + const handleSubscribe = (e: React.FormEvent) => { + e.preventDefault(); + if (!email) return; + toast.success("Subscribed to changelog updates!"); + setEmail(""); + }; + + return ( +
+
+ +
+ {/* Header */} +
+ Changelog +

What is new in DevStack

+

All the latest updates, improvements, and fixes.

+
+ + {/* Subscribe */} + + +
+
+ + setEmail(e.target.value)} + className="bg-slate-950 border-slate-700 text-white placeholder:text-slate-600 focus:border-emerald-500" + /> +
+ +
+
+
+ + {/* Filters */} +
+ {filterOptions.map((opt) => ( + + ))} +
+ + {/* Release entries */} +
+ {filtered.map((release) => ( + + +
+ + v{release.version} + + {release.date} +
+ {release.changes.map((type) => { + const cfg = typeConfig[type]; + return ( + + + {cfg.label} + + ); + })} +
+
+

{release.title}

+

{release.description}

+
+
+ ))} +
+ + {filtered.length === 0 && ( +
+

No entries matching this filter.

+
+ )} +
+ +
+ ); +}