UI: complete redesign — warm atelier style, Manrope font, burnt orange accent, shadow-based cards
This commit is contained in:
@@ -6,7 +6,7 @@ import { useAuth } from '@/hooks/useAuth';
|
||||
import { useToast } from '@/components/Toast';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
|
||||
import { ArrowLeft, Upload, X } from 'lucide-react';
|
||||
import { ArrowLeft, Upload, X, ImagePlus } from 'lucide-react';
|
||||
|
||||
export default function UploadPage() {
|
||||
const navigate = useNavigate();
|
||||
@@ -41,60 +41,65 @@ export default function UploadPage() {
|
||||
const clearFile = () => { setFile(null); if (preview) URL.revokeObjectURL(preview); setPreview(null); };
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-[580px] px-4 py-6">
|
||||
<div className="mx-auto max-w-[520px] px-5 py-6">
|
||||
<button onClick={() => navigate(-1)}
|
||||
className="mb-5 flex items-center gap-1.5 text-xs text-[var(--fg-secondary)] hover:text-[var(--fg)] transition-colors">
|
||||
<ArrowLeft className="h-4 w-4 stroke-[1.5]" /> Назад
|
||||
className="mb-6 flex items-center gap-1.5 text-xs text-[var(--fg-tertiary)] hover:text-[var(--fg)] transition-colors">
|
||||
<ArrowLeft className="h-4 w-4" strokeWidth={1.5} /> Назад
|
||||
</button>
|
||||
|
||||
<h1 className="text-xl font-bold mb-6 text-gradient">Новая публикация</h1>
|
||||
<h1 className="text-xl font-800 tracking-tight mb-6">Новая публикация</h1>
|
||||
|
||||
{!preview ? (
|
||||
<div {...getRootProps()}
|
||||
className={`border-2 border-dashed rounded-xl p-14 text-center cursor-pointer transition-all ${
|
||||
isDragActive ? 'border-[var(--primary)] bg-[var(--primary-soft)] scale-[1.01]' : 'border-[var(--border)] hover:bg-[var(--secondary)]'
|
||||
className={`border-2 border-dashed rounded-2xl p-16 text-center cursor-pointer transition-all bg-white ${
|
||||
isDragActive ? 'border-[var(--accent)] bg-[var(--accent-light)] scale-[1.01]' : 'border-[var(--border)] hover:border-[var(--fg-tertiary)] hover:bg-[var(--surface-hover)]'
|
||||
}`}>
|
||||
<input {...getInputProps()} />
|
||||
<div className="mb-5 flex justify-center">
|
||||
<div className="h-14 w-14 rounded-xl bg-[var(--secondary)] flex items-center justify-center">
|
||||
<Upload className="h-6 w-6 text-[var(--fg-secondary)]" strokeWidth={1.5} />
|
||||
<div className="h-14 w-14 rounded-2xl bg-[var(--accent-light)] flex items-center justify-center">
|
||||
<ImagePlus className="h-6 w-6 text-[var(--accent)]" strokeWidth={1.5} />
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm font-semibold mb-1">{isDragActive ? 'Отпустите фото' : 'Перетащите фото'}</p>
|
||||
<p className="text-xs text-[var(--fg-secondary)] mb-5">или нажмите, чтобы выбрать</p>
|
||||
<Button variant="outline" size="sm" className="rounded-lg text-xs px-5">Выбрать файл</Button>
|
||||
<p className="mt-4 text-[11px] text-[var(--fg-tertiary)]">JPG, PNG, GIF, WebP · до 10 МБ</p>
|
||||
<p className="text-sm font-semibold mb-1">{isDragActive ? 'Отпустите фото' : 'Перетащите фото сюда'}</p>
|
||||
<p className="text-xs text-[var(--fg-tertiary)] mb-5">или нажмите, чтобы выбрать файл</p>
|
||||
<Button variant="outline" size="sm" className="rounded-xl text-xs px-5 h-9">Выбрать файл</Button>
|
||||
<p className="mt-4 text-[10px] text-[var(--fg-tertiary)] tracking-wide">JPG, PNG, GIF, WebP · до 10 МБ</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-5 animate-rise">
|
||||
<div className="relative bg-[var(--secondary)] rounded-xl overflow-hidden">
|
||||
<div className="space-y-5 animate-fade-up">
|
||||
<div className="relative bg-[var(--bg)] rounded-2xl overflow-hidden">
|
||||
<img src={preview!} alt="Preview" className="max-h-[420px] w-full object-contain" />
|
||||
<button onClick={clearFile}
|
||||
className="absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-full bg-black/40 text-white hover:bg-black/60 transition-all">
|
||||
className="absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-xl bg-black/40 text-white hover:bg-black/60 transition-all">
|
||||
<X className="h-4 w-4" strokeWidth={2} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3">
|
||||
<Avatar className="h-9 w-9 shrink-0 border">
|
||||
<AvatarFallback className="text-xs avatar">{user?.username?.charAt(0).toUpperCase() || '?'}</AvatarFallback>
|
||||
<Avatar className="h-9 w-9 shrink-0">
|
||||
<AvatarFallback className="text-xs avatar-colored bg-[var(--accent)]">
|
||||
{user?.username?.charAt(0).toUpperCase() || '?'}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-semibold mb-1">{user?.username}</p>
|
||||
<textarea placeholder="Подпись..." value={caption} onChange={(e) => setCaption(e.target.value)}
|
||||
<textarea placeholder="Подпись..." value={caption} onChange={e => setCaption(e.target.value)}
|
||||
maxLength={200} rows={3}
|
||||
className="w-full resize-none text-sm bg-transparent outline-none placeholder:text-[var(--fg-tertiary)] leading-[1.4]" />
|
||||
className="w-full resize-none text-sm bg-transparent outline-none placeholder:text-[var(--fg-tertiary)] leading-[1.5]" />
|
||||
<div className="flex justify-end mt-1">
|
||||
<span className="text-[11px] text-[var(--fg-tertiary)] tabular-nums">{caption.length}/200</span>
|
||||
<span className="text-[10px] text-[var(--fg-tertiary)] stat-value">{caption.length}/200</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between pt-3 border-t">
|
||||
<span className="text-xs text-[var(--fg-secondary)]">🏆 +1 балл</span>
|
||||
<div className="divider" />
|
||||
|
||||
<div className="flex items-center justify-between pt-1">
|
||||
<span className="text-xs text-[var(--fg-tertiary)] flex items-center gap-1">
|
||||
<Upload className="h-3 w-3" strokeWidth={1.5} /> +1 балл
|
||||
</span>
|
||||
<Button onClick={handleUpload} disabled={uploadMutation.isPending}
|
||||
size="sm" className="rounded-lg text-sm px-6 h-10 disabled:opacity-60"
|
||||
style={{ background: 'linear-gradient(135deg, #2563eb, #7c3aed)' }}>
|
||||
size="sm" className="rounded-xl text-sm px-6 h-10 bg-[var(--accent)] hover:bg-[var(--accent-hover)] text-white disabled:opacity-60">
|
||||
{uploadMutation.isPending ? (
|
||||
<span className="flex items-center gap-2">
|
||||
<span className="h-4 w-4 rounded-full border-2 border-white/30 border-t-white animate-spin" />
|
||||
@@ -105,8 +110,8 @@ export default function UploadPage() {
|
||||
</div>
|
||||
|
||||
{uploadMutation.isError && (
|
||||
<div className="flex items-center gap-2 px-4 py-3 rounded-xl bg-[var(--danger-light)] text-[var(--danger)] text-xs font-medium animate-rise">
|
||||
<span>⚠️</span><span>Не удалось загрузить. Попробуйте снова.</span>
|
||||
<div className="flex items-center gap-2 px-4 py-3 rounded-xl bg-red-50 text-red-600 text-xs font-medium animate-fade-up">
|
||||
Не удалось загрузить. Попробуйте снова.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user