Files
CC-Switch/src/lib/schemas/provider.ts
T
YoVinchen 636a1e2c60 feat(provider): integrate icon system into provider UI components
Add icon customization support to provider management interface:

## Type System Updates

### Provider Interface (src/types.ts)
- Add optional `icon` field for icon name (e.g., "openai", "anthropic")
- Add optional `iconColor` field for hex color (e.g., "#00A67E")

### Form Schema (src/lib/schemas/provider.ts)
- Extend providerSchema with icon and iconColor optional fields
- Maintain backward compatibility with existing providers

## UI Components

### ProviderCard (src/components/providers/ProviderCard.tsx)
- Display ProviderIcon alongside provider name
- Add icon container with hover animation effect
- Adjust layout spacing for icon placement
- Update translate offsets for action buttons

### BasicFormFields (src/components/providers/forms/BasicFormFields.tsx)
- Add icon preview section showing current selection
- Implement fullscreen icon picker dialog
- Auto-apply default color from icon metadata on selection
- Display provider name and icon status in preview

### AddProviderDialog & EditProviderDialog
- Pass icon fields through form submission
- Preserve icon data during provider updates

This enables users to visually distinguish providers in the list
with custom icons, improving UX for multi-provider setups.
2025-11-21 23:21:34 +08:00

61 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { z } from "zod";
/**
* 解析 JSON 语法错误,提取位置信息
*/
function parseJsonError(error: unknown): string {
if (!(error instanceof SyntaxError)) {
return "配置 JSON 格式错误";
}
const message = error.message;
// 提取位置信息:Chrome/V8: "Unexpected token ... in JSON at position 123"
const positionMatch = message.match(/at position (\d+)/i);
if (positionMatch) {
const position = parseInt(positionMatch[1], 10);
return `JSON 格式错误:${message.split(" in JSON")[0]}(位置:${position}`;
}
// Firefox: "JSON.parse: unexpected character at line 1 column 23"
const lineColumnMatch = message.match(/line (\d+) column (\d+)/i);
if (lineColumnMatch) {
const line = lineColumnMatch[1];
const column = lineColumnMatch[2];
return `JSON 格式错误:第 ${line} 行,第 ${column}`;
}
// 通用情况:提取关键错误信息
const cleanMessage = message
.replace(/^JSON\.parse:\s*/i, "")
.replace(/^Unexpected\s+/i, "意外的 ")
.replace(/token/gi, "符号")
.replace(/Expected/gi, "预期");
return `JSON 格式错误:${cleanMessage}`;
}
export const providerSchema = z.object({
name: z.string().min(1, "请填写供应商名称"),
websiteUrl: z.string().url("请输入有效的网址").optional().or(z.literal("")),
notes: z.string().optional(),
settingsConfig: z
.string()
.min(1, "请填写配置内容")
.superRefine((value, ctx) => {
try {
JSON.parse(value);
} catch (error) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: parseJsonError(error),
});
}
}),
// 图标配置
icon: z.string().optional(),
iconColor: z.string().optional(),
});
export type ProviderFormData = z.infer<typeof providerSchema>;