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
95 lines
3.3 KiB
JavaScript
95 lines
3.3 KiB
JavaScript
import React from 'react'
|
|
import UploadDropzone from '../UploadDropzone'
|
|
import ScreenshotUploader from '../ScreenshotUploader'
|
|
|
|
/**
|
|
* Step1FileUpload
|
|
*
|
|
* Step 1 of the upload wizard: file selection + live upload progress.
|
|
* Shows the dropzone, optional screenshot uploader (archives),
|
|
* and the progress panel once an upload is in flight.
|
|
*/
|
|
export default function Step1FileUpload({
|
|
headingRef,
|
|
// File state
|
|
primaryFile,
|
|
primaryPreviewUrl,
|
|
primaryErrors,
|
|
primaryWarnings,
|
|
fileMetadata,
|
|
fileSelectionLocked,
|
|
onPrimaryFileChange,
|
|
// Archive screenshots
|
|
isArchive,
|
|
screenshots,
|
|
screenshotErrors,
|
|
screenshotPerFileErrors,
|
|
onScreenshotsChange,
|
|
// Machine state (passed for potential future use)
|
|
machine,
|
|
}) {
|
|
return (
|
|
<div className="bg-panel/80 backdrop-blur rounded-2xl shadow-xl shadow-black/40 ring-1 ring-white/10 p-6 space-y-5">
|
|
{/* Step header */}
|
|
<div className="rounded-xl bg-white/[0.04] px-4 py-3 ring-1 ring-white/8">
|
|
<h2
|
|
ref={headingRef}
|
|
tabIndex={-1}
|
|
className="text-lg font-semibold text-white focus:outline-none"
|
|
>
|
|
Upload your artwork
|
|
</h2>
|
|
<p className="mt-1 text-sm text-white/60">
|
|
Drop or browse a file. Validation runs immediately. Upload starts when you click
|
|
<span className="text-white/80">Start upload</span>.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Locked notice */}
|
|
{fileSelectionLocked && (
|
|
<div className="flex items-center gap-2 rounded-lg bg-amber-500/10 px-3 py-2 text-xs text-amber-100 ring-1 ring-amber-300/30">
|
|
<svg className="h-3.5 w-3.5 shrink-0" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
<path fillRule="evenodd" d="M10 1a4.5 4.5 0 00-4.5 4.5V9H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-.5V5.5A4.5 4.5 0 0010 1zm3 8V5.5a3 3 0 10-6 0V9h6z" clipRule="evenodd" />
|
|
</svg>
|
|
File is locked after upload. Reset to change.
|
|
</div>
|
|
)}
|
|
|
|
{/* Primary dropzone */}
|
|
<UploadDropzone
|
|
title="Upload your artwork file"
|
|
description="Drag & drop or click to browse. Accepted: JPG, PNG, WEBP, ZIP, RAR, 7Z."
|
|
fileName={primaryFile?.name || ''}
|
|
previewUrl={primaryPreviewUrl}
|
|
fileMeta={fileMetadata}
|
|
fileHint="No file selected"
|
|
invalid={primaryErrors.length > 0}
|
|
errors={primaryErrors}
|
|
showLooksGood={Boolean(primaryFile) && primaryErrors.length === 0}
|
|
looksGoodText="Looks good"
|
|
locked={fileSelectionLocked}
|
|
onPrimaryFileChange={(file) => {
|
|
if (fileSelectionLocked) return
|
|
onPrimaryFileChange(file || null)
|
|
}}
|
|
/>
|
|
|
|
{/* Screenshots (archives only) */}
|
|
<ScreenshotUploader
|
|
title="Archive screenshots"
|
|
description="We need at least 1 screenshot to generate thumbnails and analyze content."
|
|
visible={isArchive}
|
|
files={screenshots}
|
|
min={1}
|
|
max={5}
|
|
perFileErrors={screenshotPerFileErrors}
|
|
errors={screenshotErrors}
|
|
invalid={isArchive && screenshotErrors.length > 0}
|
|
showLooksGood={isArchive && screenshots.length > 0 && screenshotErrors.length === 0}
|
|
looksGoodText="Looks good"
|
|
onFilesChange={onScreenshotsChange}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|