import { Modal, Center, Group, TextInput, Image, Button, Select, LoadingOverlay, ActionIcon, Tooltip, Title, Anchor, Text, } from '@mantine/core'; import { useForm } from '@mantine/form'; import { useState } from 'react'; import { Apps } from 'tabler-icons-react'; import { v4 as uuidv4 } from 'uuid'; import { useConfig } from '../../tools/state'; import { ServiceTypeList } from '../../tools/types'; export function AddItemShelfButton(props: any) { const [opened, setOpened] = useState(false); return ( <> Add service} opened={props.opened || opened} onClose={() => setOpened(false)} > setOpened(true)} > ); } function MatchIcon(name: string, form: any) { fetch( `https://cdn.jsdelivr.net/gh/walkxhub/dashboard-icons/png/${name .replace(/\s+/g, '-') .toLowerCase()}.png` ).then((res) => { if (res.ok) { form.setFieldValue('icon', res.url); } }); return false; } function MatchService(name: string, form: any) { const service = ServiceTypeList.find((s) => s === name); if (service) { form.setFieldValue('type', service); } } function MatchPort(name: string, form: any) { const portmap = [ { name: 'qBittorrent', value: '8080' }, { name: 'Sonarr', value: '8989' }, { name: 'Radarr', value: '7878' }, { name: 'Lidarr', value: '8686' }, { name: 'Readarr', value: '8686' }, { name: 'Deluge', value: '8112' }, { name: 'Transmission', value: '9091' }, ]; // Match name with portmap key const port = portmap.find((p) => p.name === name); console.log('port', port); if (port) { form.setFieldValue('url', `http://localhost:${port.value}`); } } export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & any) { const { setOpened } = props; const { config, setConfig } = useConfig(); const [isLoading, setLoading] = useState(false); const form = useForm({ initialValues: { id: props.id ?? uuidv4(), type: props.type ?? 'Other', name: props.name ?? '', icon: props.icon ?? '/favicon.svg', url: props.url ?? '', apiKey: props.apiKey ?? (undefined as unknown as string), username: props.username ?? (undefined as unknown as string), password: props.password ?? (undefined as unknown as string), }, validate: { apiKey: () => null, // Validate icon with a regex icon: (value: string) => { // Regex to match everything that ends with and icon extension if (!value.match(/\.(png|jpg|jpeg|gif|svg)$/)) { return 'Please enter a valid icon URL'; } return null; }, // Validate url with a regex http/https url: (value: string) => { try { const _isValid = new URL(value); } catch (e) { return 'Please enter a valid URL'; } return null; }, }, }); return ( <>
Placeholder
{ // If service already exists, update it. if (config.services && config.services.find((s) => s.id === form.values.id)) { setConfig({ ...config, // replace the found item by matching ID services: config.services.map((s) => { if (s.id === form.values.id) { return { ...form.values, }; } return s; }), }); } else { setConfig({ ...config, services: [...config.services, form.values], }); } setOpened(false); form.reset(); })} > { form.setFieldValue('name', event.currentTarget.value); MatchIcon(event.currentTarget.value, form); MatchService(event.currentTarget.value, form); MatchPort(event.currentTarget.value, form); }} error={form.errors.name && 'Invalid icon url'} />