diff --git a/src/pages/Article.tsx b/src/pages/Article.tsx new file mode 100644 index 0000000..af69d9c --- /dev/null +++ b/src/pages/Article.tsx @@ -0,0 +1,417 @@ +import { useState, useEffect } from "react"; +import { Link, useParams } from "react-router-dom"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { Avatar, AvatarFallback } from "@/components/ui/avatar"; +import { Textarea } from "@/components/ui/textarea"; +import { Separator } from "@/components/ui/separator"; +import { Input } from "@/components/ui/input"; +import { toast } from "sonner"; +import { + ArrowRight, Clock, Twitter, Facebook, Linkedin, Link2, + ChevronRight, MessageSquare, ThumbsUp, Bookmark, Share2, Globe, Mail +} from "lucide-react"; +import { useSaas, useSaasMutation } from "@/hooks/use-tygarun"; +import Header from "@/components/Header"; +import Footer from "@/components/Footer"; + +const categoryColors: Record = { + Technology: "bg-emerald-100 text-emerald-700", + Design: "bg-amber-100 text-amber-700", + Business: "bg-stone-200 text-stone-700", + Lifestyle: "bg-teal-100 text-teal-700", +}; + +const relatedArticles = [ + { id: 1, title: "TypeScript Best Practices for Large Codebases", category: "Technology", author: "James Liu", date: "Mar 6, 2025", gradient: "from-amber-100 to-amber-300", slug: "typescript-best-practices" }, + { id: 2, title: "Accessible UI Patterns Every Developer Should Know", category: "Design", author: "David Kim", date: "Mar 2, 2025", gradient: "from-emerald-100 to-emerald-300", slug: "accessible-ui-patterns" }, + { id: 3, title: "State Management in 2025: What Actually Works", category: "Technology", author: "Sarah Chen", date: "Feb 28, 2025", gradient: "from-stone-200 to-stone-400", slug: "state-management-2025" }, +]; + +const seedComments = [ + { id: 1, author: "Alex Thompson", date: "2 days ago", text: "Excellent article! The section on edge computing really resonated with the challenges we face at our company. Would love to see a follow-up on specific migration strategies.", initials: "AT" }, + { id: 2, author: "Maya Johnson", date: "1 day ago", text: "I think the shift toward server components is the most interesting trend here. It fundamentally changes how we think about component architecture.", initials: "MJ" }, + { id: 3, author: "Ryan Park", date: "5 hours ago", text: "Great read. One thing I would add is the role of WebAssembly in this evolution. It opens up possibilities for languages beyond JavaScript on the web.", initials: "RP" }, +]; + +const tocHeadings = [ + { id: "introduction", label: "Introduction" }, + { id: "getting-started", label: "Getting Started" }, + { id: "best-practices", label: "Best Practices" }, + { id: "conclusion", label: "Conclusion" }, +]; + +export default function ArticlePage() { + const { slug } = useParams(); + const [commentText, setCommentText] = useState(""); + const [nlEmail, setNlEmail] = useState(""); + const [nlSubscribed, setNlSubscribed] = useState(false); + const [scrollProgress, setScrollProgress] = useState(0); + + // tyga.run community (comments) + notifications (newsletter). Seed until live. + const { data: liveComments, refetch: refetchComments } = useSaas("community", "/comments", { query: { postId: slug } }); + const { mutate: postComment, loading: posting } = useSaasMutation("community", "/comments"); + const { mutate: subscribeNewsletter } = useSaasMutation("email", "/send/newsletter-confirm"); + const comments = (liveComments && liveComments.length) ? liveComments : seedComments; + + const handlePostComment = async (e) => { + e.preventDefault(); + if (!commentText.trim()) return; + try { + await postComment({ postId: slug, body: commentText }); + setCommentText(""); + toast.success("Comment posted!"); + refetchComments(); + } catch { + toast.error("Could not post comment. Please try again."); + } + }; + + const handleArticleSubscribe = async (e) => { + e.preventDefault(); + if (!nlEmail) return; + try { + await subscribeNewsletter({ email: nlEmail, list: "newsletter" }); + setNlSubscribed(true); + toast.success("Subscribed! Check your inbox."); + } catch { + toast.error("Something went wrong. Please try again."); + } + }; + + useEffect(() => { + const handleScroll = () => { + const totalHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight; + const progress = totalHeight > 0 ? (window.scrollY / totalHeight) * 100 : 0; + setScrollProgress(progress); + }; + window.addEventListener("scroll", handleScroll, { passive: true }); + return () => window.removeEventListener("scroll", handleScroll); + }, []); + + return ( +
+ {/* Reading Progress Bar */} +
+
+ +
+
+ {/* Breadcrumb */} + + + {/* Article Header */} +
+ Technology +

+ The Future of Web Development: What Comes After the JavaScript Era +

+

Exploring the emerging paradigms that may reshape how we build for the web.

+
+ + {/* Author row */} +
+ + SC + +
+ Sarah Chen +

+ Mar 15, 2025 + · + 5 min read +

+
+
+ + +
+
+
+ + {/* Hero Image */} +
+
+
+
+
+
+
+ + {/* Article Body with TOC */} +
+
+ {/* Table of Contents - Desktop Only */} + + + {/* Article Content */} +
+
+

+ The web development landscape is shifting. After two decades of JavaScript dominance, new paradigms are emerging that challenge our fundamental assumptions about how web applications should be built, deployed, and experienced by users. +

+ +

The Rise of Edge Computing

+

+ Edge computing has transformed the way we think about server architecture. Instead of relying on centralized data centers, applications now run closer to the user, reducing latency and improving reliability across geographically distributed systems. +

+

+ This shift has profound implications for how we structure our applications. Traditional client-server architectures are giving way to more distributed models where the boundary between frontend and backend becomes increasingly blurred. +

+ +
+

+ + The best code is the code that never has to run on the client. The future of web development is about moving computation to where it makes the most sense. +

+
+ +

Practical Implications for Developers

+

+ For developers, this means rethinking many of the patterns we have relied on. State management, data fetching, and rendering strategies all need to be reconsidered in light of these new architectural possibilities. +

+ + {/* Code Block */} +
+
+
+
+
+ component.tsx +
+
+{String.raw`// Example: Modern component pattern
+interface ComponentProps {
+  variant?: "default" | "outline" | "ghost";
+  size?: "sm" | "md" | "lg";
+  children: React.ReactNode;
+}
+
+export function Component({
+  variant = "default",
+  size = "md",
+  children,
+}: ComponentProps) {
+  return (
+    
+ {children} +
+ ); +}`} +
+
+ +

What This Means for the Future

+

+ Looking ahead, we can expect to see continued convergence between traditionally separate concerns. The distinction between build-time and run-time, between static and dynamic, will continue to dissolve. +

+

+ The developers who thrive will be those who embrace these changes rather than resist them, building mental models that are flexible enough to accommodate the rapid pace of innovation in our field. +

+
+ + {/* Inline Newsletter CTA */} + + + +

Join 12,000+ readers

+

Enjoyed this? Subscribe for more

+

Get articles like this delivered to your inbox every week.

+
+ Weekly insights + · + No spam + · + Unsubscribe anytime +
+ {nlSubscribed ? ( +

You are subscribed! Check your inbox.

+ ) : ( +
+ setNlEmail(e.target.value)} + className="border-stone-200 focus-visible:ring-emerald-500" + /> + +
+ )} +

+ + Your email is safe with us +

+
+
+ + {/* Share Buttons */} + +
+ Share this article +
+ + + + +
+
+ + {/* Author Bio */} + + +
+
+
+
+ SC +
+
+
+
+

Written by

+ Sarah Chen +

Senior Software Engineer & Technical Writer

+

+ Sarah is a senior software engineer and technical writer specializing in frontend architecture. She has been building for the web for over 10 years and loves exploring the intersection of developer experience and user experience. +

+
+ + + + + + More from this author + +
+
+
+
+
+ + {/* Related Articles */} +
+

Related Articles

+
+ {relatedArticles.map((article) => ( + + +
+
+
+
+ + + {article.category} + +

+ {article.title} +

+

{article.author} · {article.date}

+
+ + + ))} +
+
+ + {/* Comments Section */} +
+

+ Comments +

+

{comments.length} comments

+ +
+ {comments.map((comment) => ( +
+ + {comment.initials || (comment.author || "?").slice(0, 2).toUpperCase()} + +
+
+ {comment.author} + {comment.date || (comment.createdAt ? new Date(comment.createdAt).toLocaleDateString() : "")} +
+

{comment.text || comment.body}

+
+ + +
+
+
+ ))} +
+ + + + {/* Comment Form */} +
+

Leave a Comment

+