feat: forum rich-text editor, emoji picker, mentions, discover nav, feed, uploads, profile

Forum:
- TipTap WYSIWYG editor with full toolbar
- @emoji-mart/react emoji picker (consistent with tweets)
- @mention autocomplete with user search API
- Fix PHP 8.4 parse errors in Blade templates
- Fix thread data display (paginator items)
- Align forum page widths to max-w-5xl

Discover:
- Extract shared _nav.blade.php partial
- Add missing nav links to for-you page
- Add Following link for authenticated users

Feed/Posts:
- Post model, controllers, policies, migrations
- Feed page components (PostComposer, FeedCard, etc)
- Post reactions, comments, saves, reports, sharing
- Scheduled publishing support
- Link preview controller

Profile:
- Profile page components (ProfileHero, ProfileTabs)
- Profile API controller

Uploads:
- Upload wizard enhancements
- Scheduled publish picker
- Studio status bar and readiness checklist
This commit is contained in:
2026-03-03 09:48:31 +01:00
parent 1266f81d35
commit dc51d65440
178 changed files with 14308 additions and 665 deletions

View File

@@ -0,0 +1,74 @@
import React, { useState, useCallback } from 'react'
import Breadcrumbs from '../../components/forum/Breadcrumbs'
import Button from '../../components/ui/Button'
import RichTextEditor from '../../components/forum/RichTextEditor'
export default function ForumEditPost({ post, thread, csrfToken, errors = {} }) {
const [content, setContent] = useState(post?.content ?? '')
const [submitting, setSubmitting] = useState(false)
const breadcrumbs = [
{ label: 'Home', href: '/' },
{ label: 'Forum', href: '/forum' },
{ label: thread?.title ?? 'Thread', href: thread?.id ? `/forum/thread/${thread.id}-${thread.slug ?? ''}` : '/forum' },
{ label: 'Edit post' },
]
const handleSubmit = useCallback((e) => {
if (submitting) return
setSubmitting(true)
// Let the form submit normally for PRG
}, [submitting])
return (
<div className="px-4 pt-10 pb-20 sm:px-6 lg:px-8 max-w-3xl mx-auto">
<Breadcrumbs items={breadcrumbs} />
{/* Header */}
<div className="mt-5 mb-6">
<p className="text-xs font-semibold uppercase tracking-widest text-white/30 mb-1">Edit</p>
<h1 className="text-2xl font-bold text-white leading-tight">Edit post</h1>
</div>
{/* Form */}
<form
method="POST"
action={`/forum/post/${post?.id}`}
onSubmit={handleSubmit}
className="space-y-5 rounded-2xl border border-white/[0.06] bg-nova-800/50 p-6 backdrop-blur"
>
<input type="hidden" name="_token" value={csrfToken} />
<input type="hidden" name="_method" value="PUT" />
{/* Rich text editor */}
<div>
<label className="mb-1.5 block text-sm font-medium text-white/85">
Content
</label>
<RichTextEditor
content={content}
onChange={setContent}
placeholder="Edit your post…"
error={errors.content}
minHeight={14}
autofocus={false}
/>
<input type="hidden" name="content" value={content} />
</div>
{/* Actions */}
<div className="flex items-center justify-between pt-2">
<a
href={thread?.id ? `/forum/thread/${thread.id}-${thread.slug ?? ''}` : '/forum'}
className="text-sm text-zinc-500 hover:text-zinc-300 transition-colors"
>
Cancel
</a>
<Button type="submit" variant="primary" size="md" loading={submitting}>
Save changes
</Button>
</div>
</form>
</div>
)
}