- Fork elmeg-demo codebase for multi-band support - Add data importer infrastructure with base class - Create band-specific importers: - phish.py: Phish.net API v5 - grateful_dead.py: Grateful Stats API - setlistfm.py: Dead & Company, Billy Strings (Setlist.fm) - Add spec-kit configuration for Gemini - Update README with supported bands and architecture
80 lines
2.7 KiB
TypeScript
80 lines
2.7 KiB
TypeScript
"use client"
|
|
|
|
import { Button } from "@/components/ui/button"
|
|
import { Textarea } from "@/components/ui/textarea"
|
|
import { useState } from "react"
|
|
import { getApiUrl } from "@/lib/api-config"
|
|
|
|
interface GroupFeedProps {
|
|
groupId: number
|
|
initialPosts?: any[]
|
|
}
|
|
|
|
export function GroupFeed({ groupId, initialPosts = [] }: GroupFeedProps) {
|
|
const [posts, setPosts] = useState(initialPosts)
|
|
const [newPost, setNewPost] = useState("")
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault()
|
|
if (!newPost.trim()) return
|
|
|
|
const token = localStorage.getItem("token")
|
|
if (!token) {
|
|
alert("Please log in to post.")
|
|
return
|
|
}
|
|
|
|
setLoading(true)
|
|
try {
|
|
const res = await fetch(`${getApiUrl()}/groups/${groupId}/posts`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`
|
|
},
|
|
body: JSON.stringify({ content: newPost, group_id: groupId })
|
|
})
|
|
|
|
if (!res.ok) throw new Error("Failed to post")
|
|
|
|
const savedPost = await res.json()
|
|
setPosts(prev => [savedPost, ...prev])
|
|
setNewPost("")
|
|
} catch (err) {
|
|
console.error(err)
|
|
alert("Error posting to group")
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
<Textarea
|
|
placeholder="Share something with the group..."
|
|
value={newPost}
|
|
onChange={(e) => setNewPost(e.target.value)}
|
|
/>
|
|
<Button type="submit" disabled={loading || !newPost.trim()}>
|
|
{loading ? "Posting..." : "Post"}
|
|
</Button>
|
|
</form>
|
|
|
|
<div className="space-y-4">
|
|
{posts.map((post: any) => (
|
|
<div key={post.id} className="p-4 border rounded-lg bg-card text-card-foreground shadow-sm">
|
|
<div className="flex justify-between items-start mb-2">
|
|
<span className="font-semibold text-sm">User #{post.user_id}</span>
|
|
<span className="text-xs text-muted-foreground">
|
|
{new Date(post.created_at).toLocaleDateString()}
|
|
</span>
|
|
</div>
|
|
<p className="text-sm whitespace-pre-wrap">{post.content}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|