77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
import type { Personality } from "@mosaic/shared";
|
|
import { fetchPersonalities } from "@/lib/api/personalities";
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@/components/ui/select";
|
|
import { Label } from "@/components/ui/label";
|
|
import { Badge } from "@/components/ui/badge";
|
|
|
|
interface PersonalitySelectorProps {
|
|
value?: string;
|
|
onChange?: (personalityId: string) => void;
|
|
label?: string;
|
|
className?: string;
|
|
}
|
|
|
|
export function PersonalitySelector({
|
|
value,
|
|
onChange,
|
|
label = "Select Personality",
|
|
className,
|
|
}: PersonalitySelectorProps): React.ReactElement {
|
|
const [personalities, setPersonalities] = useState<Personality[]>([]);
|
|
const [isLoading, setIsLoading] = useState<boolean>(true);
|
|
|
|
useEffect(() => {
|
|
loadPersonalities();
|
|
}, []);
|
|
|
|
async function loadPersonalities(): Promise<void> {
|
|
try {
|
|
setIsLoading(true);
|
|
const response = await fetchPersonalities();
|
|
setPersonalities(response.data);
|
|
} catch (err) {
|
|
console.error("Failed to load personalities:", err);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className={className}>
|
|
{label && (
|
|
<Label htmlFor="personality-select" className="mb-2">
|
|
{label}
|
|
</Label>
|
|
)}
|
|
<Select {...(value && { value })} {...(onChange && { onValueChange: onChange })} disabled={isLoading}>
|
|
<SelectTrigger id="personality-select">
|
|
<SelectValue placeholder={isLoading ? "Loading..." : "Choose a personality"} />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{personalities.map((personality) => (
|
|
<SelectItem key={personality.id} value={personality.id}>
|
|
<div className="flex items-center gap-2">
|
|
<span>{personality.name}</span>
|
|
{personality.isDefault && (
|
|
<Badge variant="secondary" className="ml-2">
|
|
Default
|
|
</Badge>
|
|
)}
|
|
</div>
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
);
|
|
}
|