mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 18:31:13 -05:00
106 lines
2.7 KiB
TypeScript
106 lines
2.7 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { RefreshCw, Lock } from 'lucide-react';
|
|
import { generateSlugFromName } from '@/lib/slugUtils';
|
|
|
|
interface SlugFieldProps {
|
|
name: string;
|
|
slug: string;
|
|
onSlugChange: (slug: string) => void;
|
|
isModerator: boolean;
|
|
label?: string;
|
|
hideForNonModerators?: boolean;
|
|
}
|
|
|
|
export function SlugField({
|
|
name,
|
|
slug,
|
|
onSlugChange,
|
|
isModerator,
|
|
label = 'URL Slug',
|
|
hideForNonModerators = true
|
|
}: SlugFieldProps) {
|
|
const [isEditing, setIsEditing] = useState(false);
|
|
|
|
// Auto-generate slug when name changes
|
|
useEffect(() => {
|
|
if (!isEditing && name) {
|
|
const generatedSlug = generateSlugFromName(name);
|
|
onSlugChange(generatedSlug);
|
|
}
|
|
}, [name, isEditing, onSlugChange]);
|
|
|
|
const handleRegenerate = () => {
|
|
if (name) {
|
|
const generatedSlug = generateSlugFromName(name);
|
|
onSlugChange(generatedSlug);
|
|
setIsEditing(false);
|
|
}
|
|
};
|
|
|
|
// Hide completely for non-moderators if configured
|
|
if (!isModerator && hideForNonModerators) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-2">
|
|
<div className="flex items-center gap-2">
|
|
<Label htmlFor="slug">{label}</Label>
|
|
{!isModerator && (
|
|
<Badge variant="secondary" className="text-xs">
|
|
<Lock className="w-3 h-3 mr-1" />
|
|
Auto-generated
|
|
</Badge>
|
|
)}
|
|
{isModerator && (
|
|
<Badge variant="outline" className="text-xs">
|
|
Moderator
|
|
</Badge>
|
|
)}
|
|
</div>
|
|
|
|
<div className="flex gap-2">
|
|
<Input
|
|
id="slug"
|
|
value={slug}
|
|
onChange={(e) => {
|
|
onSlugChange(e.target.value);
|
|
setIsEditing(true);
|
|
}}
|
|
placeholder="url-slug"
|
|
readOnly={!isModerator}
|
|
className={!isModerator ? 'bg-muted cursor-not-allowed' : ''}
|
|
/>
|
|
|
|
{isModerator && (
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
size="icon"
|
|
onClick={handleRegenerate}
|
|
title="Regenerate from name"
|
|
>
|
|
<RefreshCw className="w-4 h-4" />
|
|
</Button>
|
|
)}
|
|
</div>
|
|
|
|
{!isModerator && (
|
|
<p className="text-xs text-muted-foreground">
|
|
URL will be automatically generated from the name
|
|
</p>
|
|
)}
|
|
|
|
{isModerator && slug && (
|
|
<p className="text-xs text-muted-foreground">
|
|
Preview: <span className="font-mono">.../{slug}</span>
|
|
</p>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|