docs(conversation-assistant): 📝 Refactor frontend UI components and test mocks for dashboard, processing, training, device management, and red flag moderation configurations
This commit is contained in:
parent
29d86a5507
commit
c45c72f600
15 changed files with 133 additions and 119 deletions
|
|
@ -1,7 +1,9 @@
|
|||
import styled from '@lilith/ui-styled-components';
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
import { Spinner } from '@lilith/ui-primitives';
|
||||
import styled from '@lilith/ui-styled-components';
|
||||
import { Database, Server, Cpu, CheckCircle, AlertCircle, XCircle } from 'lucide-react';
|
||||
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
|
||||
import { useClassificationStats, useMLSuggestions, useHealthStatus } from '@/api';
|
||||
import { ClassificationBadge } from '@/components/ClassificationBadge';
|
||||
|
||||
|
|
@ -238,13 +240,13 @@ const HealthIcon = styled.div<{ $status: string }>`
|
|||
height: 40px;
|
||||
border-radius: 8px;
|
||||
background-color: ${(props) => {
|
||||
if (props.$status === 'ok') return 'rgba(34, 197, 94, 0.15)';
|
||||
if (props.$status === 'unavailable' || props.$status === 'unhealthy') return 'rgba(239, 68, 68, 0.15)';
|
||||
if (props.$status === 'ok') {return 'rgba(34, 197, 94, 0.15)';}
|
||||
if (props.$status === 'unavailable' || props.$status === 'unhealthy') {return 'rgba(239, 68, 68, 0.15)';}
|
||||
return 'rgba(156, 163, 175, 0.15)';
|
||||
}};
|
||||
color: ${(props) => {
|
||||
if (props.$status === 'ok') return (props.theme as ThemeInterface).colors.success.main;
|
||||
if (props.$status === 'unavailable' || props.$status === 'unhealthy') return (props.theme as ThemeInterface).colors.error.main;
|
||||
if (props.$status === 'ok') {return (props.theme as ThemeInterface).colors.success.main;}
|
||||
if (props.$status === 'unavailable' || props.$status === 'unhealthy') {return (props.theme as ThemeInterface).colors.error.main;}
|
||||
return (props.theme as ThemeInterface).colors.text.secondary;
|
||||
}};
|
||||
`;
|
||||
|
|
@ -262,8 +264,8 @@ const HealthServiceName = styled.div`
|
|||
const HealthServiceStatus = styled.div<{ $status: string }>`
|
||||
font-size: 12px;
|
||||
color: ${(props) => {
|
||||
if (props.$status === 'ok') return (props.theme as ThemeInterface).colors.success.main;
|
||||
if (props.$status === 'unavailable' || props.$status === 'unhealthy') return (props.theme as ThemeInterface).colors.error.main;
|
||||
if (props.$status === 'ok') {return (props.theme as ThemeInterface).colors.success.main;}
|
||||
if (props.$status === 'unavailable' || props.$status === 'unhealthy') {return (props.theme as ThemeInterface).colors.error.main;}
|
||||
return (props.theme as ThemeInterface).colors.text.secondary;
|
||||
}};
|
||||
`;
|
||||
|
|
@ -279,8 +281,8 @@ const HealthMeta = styled.div`
|
|||
`;
|
||||
|
||||
function getStatusIcon(status: string) {
|
||||
if (status === 'ok') return <CheckCircle size={20} aria-hidden="true" />;
|
||||
if (status === 'unavailable' || status === 'unhealthy') return <XCircle size={20} aria-hidden="true" />;
|
||||
if (status === 'ok') {return <CheckCircle size={20} aria-hidden="true" />;}
|
||||
if (status === 'unavailable' || status === 'unhealthy') {return <XCircle size={20} aria-hidden="true" />;}
|
||||
return <AlertCircle size={20} aria-hidden="true" />;
|
||||
}
|
||||
|
||||
|
|
@ -289,12 +291,12 @@ function formatUptime(seconds: number): string {
|
|||
const hours = Math.floor((seconds % 86400) / 3600);
|
||||
const minutes = Math.floor((seconds % 3600) / 60);
|
||||
|
||||
if (days > 0) return `${days}d ${hours}h`;
|
||||
if (hours > 0) return `${hours}h ${minutes}m`;
|
||||
if (days > 0) {return `${days}d ${hours}h`;}
|
||||
if (hours > 0) {return `${hours}h ${minutes}m`;}
|
||||
return `${minutes}m`;
|
||||
}
|
||||
|
||||
export function DashboardPage() {
|
||||
export const DashboardPage = () => {
|
||||
const { data: stats, isLoading: statsLoading } = useClassificationStats();
|
||||
const { data: suggestions } = useMLSuggestions(5);
|
||||
const { data: health } = useHealthStatus();
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
import { useState } from 'react';
|
||||
import { Loader2, RefreshCw, AlertTriangle } from 'lucide-react';
|
||||
|
||||
import { useToast } from '@lilith/ui-feedback';
|
||||
import styled, { keyframes } from '@lilith/ui-styled-components';
|
||||
import { Loader2, RefreshCw, AlertTriangle } from 'lucide-react';
|
||||
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
|
||||
import {
|
||||
useProcessingStats,
|
||||
useProcessMessages,
|
||||
useReprocessAllMessages,
|
||||
} from '@/api';
|
||||
import { useToast } from '@lilith/ui-feedback';
|
||||
|
||||
|
||||
const spin = keyframes`
|
||||
from { transform: rotate(0deg); }
|
||||
|
|
@ -228,7 +232,7 @@ const SecondaryButton = styled.button`
|
|||
}
|
||||
`;
|
||||
|
||||
export function ProcessingPage() {
|
||||
export const ProcessingPage = () => {
|
||||
const { data: stats, isLoading: statsLoading } = useProcessingStats();
|
||||
const processMessages = useProcessMessages();
|
||||
const reprocessAll = useReprocessAllMessages();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import styled from '@lilith/ui-styled-components';
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
import { CheckSquare } from 'lucide-react';
|
||||
import { Spinner } from '@lilith/ui-primitives';
|
||||
import styled from '@lilith/ui-styled-components';
|
||||
import { CheckSquare } from 'lucide-react';
|
||||
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
|
||||
import {
|
||||
useMLSuggestions,
|
||||
useAcceptMLSuggestion,
|
||||
|
|
@ -83,7 +85,7 @@ const EmptyText = styled.p`
|
|||
margin: 0;
|
||||
`;
|
||||
|
||||
export function ReviewQueuePage() {
|
||||
export const ReviewQueuePage = () => {
|
||||
const { data: suggestions, isLoading } = useMLSuggestions(50);
|
||||
const acceptMutation = useAcceptMLSuggestion();
|
||||
const rejectMutation = useRejectMLSuggestion();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { Link } from '@lilith/ui-router';
|
||||
import styled from '@lilith/ui-styled-components';
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
import { Palette, ShieldAlert, BookOpen, ChevronRight } from 'lucide-react';
|
||||
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
|
||||
const Container = styled.div`
|
||||
max-width: 900px;
|
||||
`;
|
||||
|
|
@ -90,8 +91,7 @@ const Arrow = styled(ChevronRight)`
|
|||
}
|
||||
`;
|
||||
|
||||
export function SettingsPage() {
|
||||
return (
|
||||
export const SettingsPage = () => (
|
||||
<Container>
|
||||
<Header>
|
||||
<h1>Settings</h1>
|
||||
|
|
@ -145,5 +145,4 @@ export function SettingsPage() {
|
|||
</Card>
|
||||
</Grid>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
import { useParams, Link } from '@lilith/ui-router';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { ArrowLeft } from 'lucide-react';
|
||||
|
||||
import styles from './StudioPage.module.css';
|
||||
|
||||
import {
|
||||
useConversation,
|
||||
useMessagesAll,
|
||||
useConversationPrimer,
|
||||
} from '@/api';
|
||||
import { useAutoRefreshPrimer } from '@/hooks/useAutoRefreshPrimer';
|
||||
import { StudioLayout } from '@/components/studio/StudioLayout';
|
||||
import { MessagesPanel } from '@/components/studio/MessagesPanel';
|
||||
import { AnalysisPanel } from '@/components/studio/AnalysisPanel';
|
||||
import styles from './StudioPage.module.css';
|
||||
import { MessagesPanel } from '@/components/studio/MessagesPanel';
|
||||
import { StudioLayout } from '@/components/studio/StudioLayout';
|
||||
import { useAutoRefreshPrimer } from '@/hooks/useAutoRefreshPrimer';
|
||||
|
||||
export function StudioPage() {
|
||||
export const StudioPage = () => {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
import { useState } from 'react';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import styled, { keyframes } from '@lilith/ui-styled-components';
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
import { useTrainingSamples, useTrainingJobs, useStartTrainingJob } from '@/api';
|
||||
|
||||
import { useToast } from '@lilith/ui-feedback';
|
||||
import styled, { keyframes } from '@lilith/ui-styled-components';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
|
||||
import { useTrainingSamples, useTrainingJobs, useStartTrainingJob } from '@/api';
|
||||
|
||||
|
||||
const spin = keyframes`
|
||||
from { transform: rotate(0deg); }
|
||||
|
|
@ -255,7 +259,7 @@ const EmptyState = styled.p`
|
|||
margin: 0;
|
||||
`;
|
||||
|
||||
export function TrainingPage() {
|
||||
export const TrainingPage = () => {
|
||||
const { data: samples } = useTrainingSamples();
|
||||
const { data: jobs } = useTrainingJobs();
|
||||
const startJob = useStartTrainingJob();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { Laptop, Smartphone, RefreshCw } from 'lucide-react';
|
||||
import type { Device } from '@/api';
|
||||
import { useDeactivateDevice, useResetDeviceSync } from '@/api';
|
||||
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
|
|
@ -20,11 +20,15 @@ import {
|
|||
ButtonSpinner,
|
||||
} from './styles';
|
||||
|
||||
import type { Device } from '@/api';
|
||||
|
||||
import { useDeactivateDevice, useResetDeviceSync } from '@/api';
|
||||
|
||||
interface DeviceCardProps {
|
||||
device: Device;
|
||||
}
|
||||
|
||||
export function DeviceCard({ device }: DeviceCardProps) {
|
||||
export const DeviceCard = ({ device }: DeviceCardProps) => {
|
||||
const deactivate = useDeactivateDevice();
|
||||
const resetSync = useResetDeviceSync();
|
||||
const [confirmingReset, setConfirmingReset] = useState(false);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { Spinner } from '@lilith/ui-primitives';
|
||||
import { useDevices, useSyncStats } from '@/api';
|
||||
|
||||
import { DeviceCard } from './DeviceCard';
|
||||
import { SyncStats } from './SyncStats';
|
||||
import { MaintenanceSection } from './MaintenanceSection';
|
||||
import {
|
||||
Container,
|
||||
|
|
@ -15,8 +14,11 @@ import {
|
|||
SyncSection,
|
||||
SectionHeader,
|
||||
} from './styles';
|
||||
import { SyncStats } from './SyncStats';
|
||||
|
||||
export function DevicesPage() {
|
||||
import { useDevices, useSyncStats } from '@/api';
|
||||
|
||||
export const DevicesPage = () => {
|
||||
const { data: devices, isLoading, error } = useDevices();
|
||||
const { data: syncStats } = useSyncStats();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
import { Users, MessageSquare, RefreshCw, AlertTriangle } from 'lucide-react';
|
||||
import { useToast } from '@lilith/ui-feedback';
|
||||
import {
|
||||
useBackfillContactLastMessageAt,
|
||||
useBackfillConversationLastMessageAt,
|
||||
useBackfillContactDisplayNames,
|
||||
} from '@/api';
|
||||
import { Users, MessageSquare, RefreshCw, AlertTriangle } from 'lucide-react';
|
||||
|
||||
import {
|
||||
MaintenanceContainer,
|
||||
MaintenanceInfo,
|
||||
|
|
@ -14,7 +10,14 @@ import {
|
|||
ButtonSpinner,
|
||||
} from './styles';
|
||||
|
||||
export function MaintenanceSection() {
|
||||
import {
|
||||
useBackfillContactLastMessageAt,
|
||||
useBackfillConversationLastMessageAt,
|
||||
useBackfillContactDisplayNames,
|
||||
} from '@/api';
|
||||
|
||||
|
||||
export const MaintenanceSection = () => {
|
||||
const backfillContactLastMessage = useBackfillContactLastMessageAt();
|
||||
const backfillConversationLastMessage = useBackfillConversationLastMessageAt();
|
||||
const backfillDisplayNames = useBackfillContactDisplayNames();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { MessageSquare, Database, Users } from 'lucide-react';
|
||||
import type { SyncStats as SyncStatsType } from '@/api';
|
||||
|
||||
import {
|
||||
StatsGrid,
|
||||
StatCard,
|
||||
|
|
@ -9,12 +9,13 @@ import {
|
|||
StatLabel,
|
||||
} from './styles';
|
||||
|
||||
import type { SyncStats as SyncStatsType } from '@/api';
|
||||
|
||||
interface SyncStatsProps {
|
||||
stats: SyncStatsType | undefined;
|
||||
}
|
||||
|
||||
export function SyncStats({ stats }: SyncStatsProps) {
|
||||
return (
|
||||
export const SyncStats = ({ stats }: SyncStatsProps) => (
|
||||
<StatsGrid>
|
||||
<StatCard>
|
||||
<StatIcon>
|
||||
|
|
@ -50,5 +51,4 @@ export function SyncStats({ stats }: SyncStatsProps) {
|
|||
</StatInfo>
|
||||
</StatCard>
|
||||
</StatsGrid>
|
||||
);
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import styled, { keyframes } from '@lilith/ui-styled-components';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
|
||||
export const spin = keyframes`
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
import { useState, useMemo } from 'react';
|
||||
import styled from '@lilith/ui-styled-components';
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
import { ArrowLeft, Loader2, AlertTriangle, MessageSquare, ChevronDown, ChevronUp } from 'lucide-react';
|
||||
|
||||
import { Link } from '@lilith/ui-router';
|
||||
import { TabGroup, SeverityBadge } from '@/components/settings';
|
||||
import styled from '@lilith/ui-styled-components';
|
||||
import { ArrowLeft, Loader2, AlertTriangle, MessageSquare, ChevronDown, ChevronUp } from 'lucide-react';
|
||||
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
|
||||
import { useRedFlagDocumentation, type RedFlagDoc } from '@/api';
|
||||
import { TabGroup, SeverityBadge } from '@/components/settings';
|
||||
|
||||
const Container = styled.div`
|
||||
max-width: 900px;
|
||||
|
|
@ -188,7 +191,7 @@ const EmptyState = styled.div`
|
|||
color: ${(props) => (props.theme as ThemeInterface).colors.text.secondary};
|
||||
`;
|
||||
|
||||
const CATEGORY_TABS: { id: string; label: string }[] = [
|
||||
const CATEGORY_TABS: Array<{ id: string; label: string }> = [
|
||||
{ id: 'all', label: 'All' },
|
||||
{ id: 'scam', label: 'Scams' },
|
||||
{ id: 'freeloader', label: 'Freeloaders' },
|
||||
|
|
@ -197,13 +200,13 @@ const CATEGORY_TABS: { id: string; label: string }[] = [
|
|||
{ id: 'payment_scam', label: 'Payment Scams' },
|
||||
];
|
||||
|
||||
export function RedFlagDocsPage() {
|
||||
export const RedFlagDocsPage = () => {
|
||||
const { data: docs, isLoading } = useRedFlagDocumentation();
|
||||
const [activeTab, setActiveTab] = useState('all');
|
||||
const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());
|
||||
|
||||
const tabsWithCounts = useMemo(() => {
|
||||
if (!docs) return CATEGORY_TABS;
|
||||
if (!docs) {return CATEGORY_TABS;}
|
||||
return CATEGORY_TABS.map((tab) => ({
|
||||
...tab,
|
||||
count: tab.id === 'all' ? docs.length : docs.filter((d) => d.category === tab.id).length,
|
||||
|
|
@ -211,8 +214,8 @@ export function RedFlagDocsPage() {
|
|||
}, [docs]);
|
||||
|
||||
const filteredDocs = useMemo(() => {
|
||||
if (!docs) return [];
|
||||
if (activeTab === 'all') return docs;
|
||||
if (!docs) {return [];}
|
||||
if (activeTab === 'all') {return docs;}
|
||||
return docs.filter((d) => d.category === activeTab);
|
||||
}, [docs, activeTab]);
|
||||
|
||||
|
|
@ -273,7 +276,7 @@ export function RedFlagDocsPage() {
|
|||
);
|
||||
}
|
||||
|
||||
function DocCardComponent({
|
||||
const DocCardComponent = ({
|
||||
doc,
|
||||
expanded,
|
||||
onToggle,
|
||||
|
|
@ -281,8 +284,7 @@ function DocCardComponent({
|
|||
doc: RedFlagDoc;
|
||||
expanded: boolean;
|
||||
onToggle: () => void;
|
||||
}) {
|
||||
return (
|
||||
}) => (
|
||||
<DocCard>
|
||||
<DocHeader onClick={onToggle}>
|
||||
<div>
|
||||
|
|
@ -335,5 +337,4 @@ function DocCardComponent({
|
|||
)}
|
||||
</DocContent>
|
||||
</DocCard>
|
||||
);
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import { useState, useMemo } from 'react';
|
||||
import styled from '@lilith/ui-styled-components';
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
import { ArrowLeft, Plus, Loader2 } from 'lucide-react';
|
||||
import { Link } from '@lilith/ui-router';
|
||||
|
||||
import { useToast } from '@lilith/ui-feedback';
|
||||
import { TabGroup, PatternCard } from '@/components/settings';
|
||||
import { Link } from '@lilith/ui-router';
|
||||
import styled from '@lilith/ui-styled-components';
|
||||
import { ArrowLeft, Plus, Loader2 } from 'lucide-react';
|
||||
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
|
||||
import {
|
||||
useRedFlagPatterns,
|
||||
useUpdateRedFlagPattern,
|
||||
|
|
@ -14,6 +16,7 @@ import {
|
|||
type RedFlagCategory,
|
||||
type RedFlagSeverity,
|
||||
} from '@/api';
|
||||
import { TabGroup, PatternCard } from '@/components/settings';
|
||||
|
||||
const Container = styled.div`
|
||||
max-width: 900px;
|
||||
|
|
@ -241,7 +244,7 @@ const SEVERITY_TABS = [
|
|||
{ id: 'custom', label: 'Custom' },
|
||||
];
|
||||
|
||||
const CATEGORIES: { value: RedFlagCategory; label: string }[] = [
|
||||
const CATEGORIES: Array<{ value: RedFlagCategory; label: string }> = [
|
||||
{ value: 'scam', label: 'Scam' },
|
||||
{ value: 'freeloader', label: 'Freeloader' },
|
||||
{ value: 'time_waste', label: 'Time Waste' },
|
||||
|
|
@ -249,7 +252,7 @@ const CATEGORIES: { value: RedFlagCategory; label: string }[] = [
|
|||
{ value: 'payment_scam', label: 'Payment Scam' },
|
||||
];
|
||||
|
||||
const SEVERITIES: { value: RedFlagSeverity; label: string }[] = [
|
||||
const SEVERITIES: Array<{ value: RedFlagSeverity; label: string }> = [
|
||||
{ value: 'CRITICAL', label: 'Critical (1.0)' },
|
||||
{ value: 'HIGH', label: 'High (0.8)' },
|
||||
{ value: 'MEDIUM', label: 'Medium (0.5)' },
|
||||
|
|
@ -276,7 +279,7 @@ const INITIAL_FORM: NewPatternForm = {
|
|||
weight: 0.5,
|
||||
};
|
||||
|
||||
export function RedFlagsConfigPage() {
|
||||
export const RedFlagsConfigPage = () => {
|
||||
const { data: patterns, isLoading } = useRedFlagPatterns();
|
||||
const updatePattern = useUpdateRedFlagPattern();
|
||||
const createPattern = useCreateCustomPattern();
|
||||
|
|
@ -288,7 +291,7 @@ export function RedFlagsConfigPage() {
|
|||
const [formData, setFormData] = useState<NewPatternForm>(INITIAL_FORM);
|
||||
|
||||
const tabsWithCounts = useMemo(() => {
|
||||
if (!patterns) return SEVERITY_TABS;
|
||||
if (!patterns) {return SEVERITY_TABS;}
|
||||
return SEVERITY_TABS.map((tab) => ({
|
||||
...tab,
|
||||
count:
|
||||
|
|
@ -301,9 +304,9 @@ export function RedFlagsConfigPage() {
|
|||
}, [patterns]);
|
||||
|
||||
const filteredPatterns = useMemo(() => {
|
||||
if (!patterns) return [];
|
||||
if (activeTab === 'all') return patterns;
|
||||
if (activeTab === 'custom') return patterns.filter((p) => p.isCustom);
|
||||
if (!patterns) {return [];}
|
||||
if (activeTab === 'all') {return patterns;}
|
||||
if (activeTab === 'custom') {return patterns.filter((p) => p.isCustom);}
|
||||
return patterns.filter((p) => p.severity === activeTab);
|
||||
}, [patterns, activeTab]);
|
||||
|
||||
|
|
@ -330,8 +333,8 @@ export function RedFlagsConfigPage() {
|
|||
};
|
||||
|
||||
const handleDelete = async (pattern: RedFlagPattern) => {
|
||||
if (!pattern.isCustom) return;
|
||||
if (!window.confirm(`Delete custom pattern "${pattern.displayName}"?`)) return;
|
||||
if (!pattern.isCustom) {return;}
|
||||
if (!window.confirm(`Delete custom pattern "${pattern.displayName}"?`)) {return;}
|
||||
|
||||
try {
|
||||
await deletePattern.mutateAsync(pattern.id);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,19 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import styled from '@lilith/ui-styled-components';
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
import { ArrowLeft, Save, Loader2 } from 'lucide-react';
|
||||
import { Link } from '@lilith/ui-router';
|
||||
|
||||
import { useToast } from '@lilith/ui-feedback';
|
||||
import { Slider, EditableTagList } from '@/components/settings';
|
||||
import { Link } from '@lilith/ui-router';
|
||||
import styled from '@lilith/ui-styled-components';
|
||||
import { ArrowLeft, Save, Loader2 } from 'lucide-react';
|
||||
|
||||
import type { ThemeInterface } from '@lilith/ui-theme';
|
||||
|
||||
import {
|
||||
useStyleProfile,
|
||||
useUpdateStyleProfile,
|
||||
type StyleProfile,
|
||||
type PunctuationStyle,
|
||||
} from '@/api';
|
||||
import { Slider, EditableTagList } from '@/components/settings';
|
||||
|
||||
const Container = styled.div`
|
||||
max-width: 800px;
|
||||
|
|
@ -177,7 +180,7 @@ const DEFAULT_DEFLECTION = [
|
|||
'Subscribe to see more of me...',
|
||||
];
|
||||
|
||||
export function StyleProfilePage() {
|
||||
export const StyleProfilePage = () => {
|
||||
const { data: profile, isLoading } = useStyleProfile();
|
||||
const updateProfile = useUpdateStyleProfile();
|
||||
const toast = useToast();
|
||||
|
|
|
|||
|
|
@ -112,27 +112,21 @@ export const mockTrainingJobs = [
|
|||
// Request handlers
|
||||
export const handlers = [
|
||||
// Devices
|
||||
http.get(`${API_BASE}/devices`, () => {
|
||||
return HttpResponse.json({
|
||||
http.get(`${API_BASE}/devices`, () => HttpResponse.json({
|
||||
success: true,
|
||||
data: mockDevices,
|
||||
});
|
||||
}),
|
||||
})),
|
||||
|
||||
http.post(`${API_BASE}/devices/:id/deactivate`, ({ params }) => {
|
||||
return HttpResponse.json({
|
||||
http.post(`${API_BASE}/devices/:id/deactivate`, ({ params }) => HttpResponse.json({
|
||||
success: true,
|
||||
data: { id: params.id, isActive: false },
|
||||
});
|
||||
}),
|
||||
})),
|
||||
|
||||
// Conversations
|
||||
http.get(`${API_BASE}/conversations`, () => {
|
||||
return HttpResponse.json({
|
||||
http.get(`${API_BASE}/conversations`, () => HttpResponse.json({
|
||||
success: true,
|
||||
data: mockConversations,
|
||||
});
|
||||
}),
|
||||
})),
|
||||
|
||||
http.get(`${API_BASE}/conversations/:id`, ({ params }) => {
|
||||
const conversation = mockConversations.find((c) => c.id === params.id);
|
||||
|
|
@ -151,12 +145,10 @@ export const handlers = [
|
|||
});
|
||||
}),
|
||||
|
||||
http.get(`${API_BASE}/conversations/:id/messages`, () => {
|
||||
return HttpResponse.json({
|
||||
http.get(`${API_BASE}/conversations/:id/messages`, () => HttpResponse.json({
|
||||
success: true,
|
||||
data: mockMessages,
|
||||
});
|
||||
}),
|
||||
})),
|
||||
|
||||
// Responses
|
||||
http.post(`${API_BASE}/responses/generate`, async ({ request }) => {
|
||||
|
|
@ -173,34 +165,26 @@ export const handlers = [
|
|||
});
|
||||
}),
|
||||
|
||||
http.post(`${API_BASE}/responses/:id/accept`, ({ params }) => {
|
||||
return HttpResponse.json({
|
||||
http.post(`${API_BASE}/responses/:id/accept`, ({ params }) => HttpResponse.json({
|
||||
success: true,
|
||||
data: { id: params.id, status: 'accepted' },
|
||||
});
|
||||
}),
|
||||
})),
|
||||
|
||||
http.post(`${API_BASE}/responses/:id/reject`, ({ params }) => {
|
||||
return HttpResponse.json({
|
||||
http.post(`${API_BASE}/responses/:id/reject`, ({ params }) => HttpResponse.json({
|
||||
success: true,
|
||||
data: { id: params.id, status: 'rejected' },
|
||||
});
|
||||
}),
|
||||
})),
|
||||
|
||||
// Training
|
||||
http.get(`${API_BASE}/training/samples`, () => {
|
||||
return HttpResponse.json({
|
||||
http.get(`${API_BASE}/training/samples`, () => HttpResponse.json({
|
||||
success: true,
|
||||
data: mockTrainingSamples,
|
||||
});
|
||||
}),
|
||||
})),
|
||||
|
||||
http.get(`${API_BASE}/training/jobs`, () => {
|
||||
return HttpResponse.json({
|
||||
http.get(`${API_BASE}/training/jobs`, () => HttpResponse.json({
|
||||
success: true,
|
||||
data: mockTrainingJobs,
|
||||
});
|
||||
}),
|
||||
})),
|
||||
|
||||
http.post(`${API_BASE}/training/jobs`, async ({ request }) => {
|
||||
const body = (await request.json()) as { baseModel: string; epochs?: number };
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue