import clsx from "clsx"; import { useTranslation } from "react-i18next"; import type { Tables } from "~/db/tables"; import { type CustomFieldRenderProps, FormField } from "~/form/FormField"; import { SendouForm, useFormFieldContext } from "~/form/SendouForm"; import { CONTROLLERS, getWidgetFormSchema, TIMEZONE_OPTIONS, } from "../core/widgets/widget-form-schemas"; import styles from "../routes/u.$identifier.module.css"; import { USER } from "../user-page-constants"; import { GameBadgeSelectField } from "./GameBadgeSelectField"; export function WidgetSettingsForm({ widget, onSettingsChange, }: { widget: Tables["UserWidget"]["widget"]; onSettingsChange: (widgetId: string, settings: unknown) => void; }) { const schema = getWidgetFormSchema(widget.id); if (!schema) { return null; } return ( ); } function WidgetSettingsFormInner({ widget, schema, onSettingsChange, }: { widget: Tables["UserWidget"]["widget"]; schema: ReturnType; onSettingsChange: (widgetId: string, settings: unknown) => void; }) { if (!schema) return null; const handleApply = (values: unknown) => { onSettingsChange(widget.id, values); }; const defaultValues = transformSettingsForForm( widget.id, widget.settings ?? {}, ); return ( ); } function WidgetFormFields({ widgetId }: { widgetId: string }) { switch (widgetId) { case "bio": case "bio-md": return ; case "x-rank-peaks": return ; case "timezone": return ; case "favorite-stage": return ; case "peak-xp-unverified": return (
); case "peak-xp-weapon": return ; case "weapon-pool": return ; case "sens": return ; case "art": return ; case "links": return ; case "tier-list": return ( {(props: CustomFieldRenderProps) => ( )} /> )} ); case "game-badges": return ( {(props: CustomFieldRenderProps) => ( )} maxCount={USER.GAME_BADGES_MAX} /> )} ); case "game-badges-small": return ( {(props: CustomFieldRenderProps) => ( )} maxCount={USER.GAME_BADGES_SMALL_MAX} /> )} ); default: return null; } } function transformSettingsForForm( widgetId: string, settings: Record, ): Record { if (widgetId === "weapon-pool" && settings.weapons) { const weapons = settings.weapons as Array<{ weaponSplId?: number; id?: number; isFavorite: number | boolean; }>; return { ...settings, weapons: weapons.map((w) => ({ id: w.id ?? w.weaponSplId, isFavorite: w.isFavorite === 1 || w.isFavorite === true, })), }; } return settings; } const SENS_OPTIONS = [ -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, ]; function SensFields() { const { t } = useTranslation(["user"]); const { values, setValue, onFieldChange } = useFormFieldContext(); const controller = (values.controller as (typeof CONTROLLERS)[number]) ?? "s2-pro-con"; const motionSens = (values.motionSens as number | null) ?? null; const stickSens = (values.stickSens as number | null) ?? null; const rawSensToString = (sens: number) => `${sens > 0 ? "+" : ""}${sens / 10}`; const handleControllerChange = ( newController: (typeof CONTROLLERS)[number], ) => { setValue("controller", newController); onFieldChange?.("controller", newController); }; const handleMotionSensChange = (sens: number | null) => { setValue("motionSens", sens); onFieldChange?.("motionSens", sens); }; const handleStickSensChange = (sens: number | null) => { setValue("stickSens", sens); onFieldChange?.("stickSens", sens); }; return (
); } function TierListField({ value, onChange }: CustomFieldRenderProps) { const { t } = useTranslation(["user"]); const handleChange = (e: React.ChangeEvent) => { const inputValue = e.target.value; if (inputValue.includes("/tier-list-maker")) { try { const url = new URL(inputValue, "https://sendou.ink"); const extractedSearchParams = url.search.substring(1); onChange(extractedSearchParams); return; } catch { // not a valid URL, just use the value as-is } } onChange(inputValue); }; return (
/tier-list-maker?
); }