sns
by@ted
A vibrant Twitter-like social media app designed for Gen Z with purple-blue gradients, emoji reactions, and real-time tweet posting/liking functionality.
Preview
Source CodeVersion 2
export default {
async fetch(request, env) {
const url = new URL(request.url);
// API routes
if (url.pathname.startsWith('/api/')) {
return handleAPI(request, env, url);
}
// Serve HTML
return new Response(getHTML(), {
headers: { 'Content-Type': 'text/html' }
});
}
};
async function handleAPI(request, env, url) {
const method = request.method;
const path = url.pathname;
try {
if (path === '/api/tweets' && method === 'GET') {
const tweets = await env.DB.prepare(`
SELECT id, content, author, created_at, likes, retweets
FROM tweets
ORDER BY created_at DESC
LIMIT 50
`).all();
return new Response(JSON.stringify({ data: tweets.results }), {
headers: { 'Content-Type': 'application/json' }
});
}
if (path === '/api/tweets' && method === 'POST') {
const { content, author } = await request.json();
if (!content || !author) {
return new Response(JSON.stringify({ error: 'Content and author required' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
const id = crypto.randomUUID();
await env.DB.prepare(`
INSERT INTO tweets (id, content, author, created_at, likes, retweets)
VALUES (?1, ?2, ?3, datetime('now'), 0, 0)
`).bind(id, content, author).run();
return new Response(JSON.stringify({ ok: true, id }), {
headers: { 'Content-Type': 'application/json' }
});
}
if (path.startsWith('/api/tweets/') && path.endsWith('/like') && method === 'POST') {
const tweetId = path.split('/')[3];
await env.DB.prepare(`
UPDATE tweets SET likes = likes + 1 WHERE id = ?1
`).bind(tweetId).run();
return new Response(JSON.stringify({ ok: true }), {
headers: { 'Content-Type': 'application/json' }
});
}
if (path.startsWith('/api/tweets/') && path.endsWith('/retweet') && method === 'POST') {
const tweetId = path.split('/')[3];
await env.DB.prepare(`
UPDATE tweets SET retweets = retweets + 1 WHERE id = ?1
`).bind(tweetId).run();
return new Response(JSON.stringify({ ok: true }), {
headers: { 'Content-Type': 'application/json' }
});
}
return new Response(JSON.stringify({ error: 'Not found' }), {
status: 404,
headers: { 'Content-Type': 'application/json' }
});
} catch (error) {
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: { 'Content-Type': 'application/json' }
});
}
}
function getHTML() {
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TweetZ - Social Network for Gen Z</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
body { font-family: 'Inter', sans-serif; }
.shimmer {
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
background-size: 200% 100%;
animation: shimmer 2s infinite;
}
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.tweet-card:hover { transform: scale(1.02); }
.gradient-bg {
background: linear-gradient(135deg, #8B5CF6, #3B82F6);
}
</style>
</head>
<body class="bg-gray-900 text-white min-h-screen">
<!-- Header -->
<header class="sticky top-0 z-50 bg-gray-900/80 backdrop-blur-lg border-b border-white/10">
<div class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between">
<h1 class="text-2xl font-bold gradient-bg bg-clip-text text-transparent">
🐦 TweetZ
</h1>
<div class="hidden md:block text-sm text-gray-400">
Where Gen Z vibes ✨
</div>
</div>
</div>
</header>
<!-- Main Content -->
<div class="container mx-auto px-4 py-6 max-w-2xl">
<!-- Tweet Composer -->
<div class="bg-white/5 backdrop-blur border border-white/10 rounded-2xl p-6 mb-8">
<div class="flex items-start space-x-4">
<div class="w-12 h-12 bg-gradient-to-br from-violet-500 to-blue-500 rounded-full flex items-center justify-center text-xl">
😊
</div>
<div class="flex-1">
<textarea
id="tweetContent"
placeholder="What's happening? Share your vibe... ✨"
class="w-full bg-transparent text-lg placeholder-gray-400 resize-none outline-none"
rows="3"
maxlength="280"
></textarea>
<div class="flex items-center justify-between mt-4">
<div class="flex items-center space-x-4">
<input
id="authorName"
type="text"
...
No comments yet. Be the first!