All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Fixes all 542 ESLint problems in the web package to achieve 0 errors and 0 warnings. Changes: - Fixed 144 issues: nullish coalescing, return types, unused variables - Fixed 118 issues: unnecessary conditions, type safety, template literals - Fixed 79 issues: non-null assertions, unsafe assignments, empty functions - Fixed 67 issues: explicit return types, promise handling, enum comparisons - Fixed 45 final warnings: missing return types, optional chains - Fixed 25 typecheck-related issues: async/await, type assertions, formatting - Fixed JSX.Element namespace errors across 90+ files All Quality Rails violations resolved. Lint and typecheck both pass with 0 problems. Files modified: 118 components, tests, hooks, and utilities Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
81 lines
2.2 KiB
TypeScript
81 lines
2.2 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(() => {
|
|
void 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>
|
|
);
|
|
}
|