🐛 fix(deps): Remove outdated @iconify/react dependency and add iconify-json packages

This commit is contained in:
web@ppanel 2025-01-18 17:39:26 +07:00
parent b0aa3645f8
commit d6fbc38795
71 changed files with 1056 additions and 227 deletions

View File

@ -1,9 +1,9 @@
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form';
import { Input } from '@workspace/ui/components/input'; import { Input } from '@workspace/ui/components/input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { Dispatch, SetStateAction } from 'react'; import { Dispatch, SetStateAction } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
@ -60,12 +60,7 @@ export default function LoginForm({
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormControl> <FormControl>
<Input <Input placeholder='Enter your password...' type='password' {...field} />
disabled={loading}
placeholder='Enter your password...'
type='password'
{...field}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>

View File

@ -1,9 +1,9 @@
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form';
import { Input } from '@workspace/ui/components/input'; import { Input } from '@workspace/ui/components/input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { Markdown } from '@workspace/ui/custom-components/markdown'; import { Markdown } from '@workspace/ui/custom-components/markdown';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { Dispatch, SetStateAction } from 'react'; import { Dispatch, SetStateAction } from 'react';
@ -102,12 +102,7 @@ export default function RegisterForm({
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormControl> <FormControl>
<Input <Input placeholder='Enter your password...' type='password' {...field} />
disabled={loading}
placeholder='Enter your password...'
type='password'
{...field}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -119,12 +114,7 @@ export default function RegisterForm({
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormControl> <FormControl>
<Input <Input placeholder='Enter password again...' type='password' {...field} />
disabled={loading}
placeholder='Enter password again...'
type='password'
{...field}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -139,7 +129,6 @@ export default function RegisterForm({
<FormControl> <FormControl>
<div className='flex items-center gap-2'> <div className='flex items-center gap-2'>
<Input <Input
disabled={loading}
placeholder='Enter code...' placeholder='Enter code...'
type='text' type='text'
{...field} {...field}

View File

@ -1,9 +1,9 @@
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form';
import { Input } from '@workspace/ui/components/input'; import { Input } from '@workspace/ui/components/input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { Dispatch, SetStateAction } from 'react'; import { Dispatch, SetStateAction } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
@ -65,12 +65,7 @@ export default function ResetForm({
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormControl> <FormControl>
<Input <Input placeholder='Enter your password...' type='password' {...field} />
disabled={loading}
placeholder='Enter your password...'
type='password'
{...field}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -86,7 +81,6 @@ export default function ResetForm({
<FormControl> <FormControl>
<div className='flex items-center gap-2'> <div className='flex items-center gap-2'>
<Input <Input
disabled={loading}
placeholder='Enter code...' placeholder='Enter code...'
type='text' type='text'
{...field} {...field}

View File

@ -1,5 +1,4 @@
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { import {
Form, Form,
@ -20,6 +19,7 @@ import {
SheetTrigger, SheetTrigger,
} from '@workspace/ui/components/sheet'; } from '@workspace/ui/components/sheet';
import { MarkdownEditor } from '@workspace/ui/custom-components/editor'; import { MarkdownEditor } from '@workspace/ui/custom-components/editor';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';

View File

@ -2,7 +2,6 @@
import { getSubscribeList } from '@/services/admin/subscribe'; import { getSubscribeList } from '@/services/admin/subscribe';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { import {
@ -26,6 +25,7 @@ import {
import { Combobox } from '@workspace/ui/custom-components/combobox'; import { Combobox } from '@workspace/ui/custom-components/combobox';
import { DatePicker } from '@workspace/ui/custom-components/date-picker'; import { DatePicker } from '@workspace/ui/custom-components/date-picker';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input'; import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { unitConversion } from '@workspace/ui/utils'; import { unitConversion } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';

View File

@ -1,5 +1,4 @@
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { import {
Form, Form,
@ -20,6 +19,7 @@ import {
SheetTrigger, SheetTrigger,
} from '@workspace/ui/components/sheet'; } from '@workspace/ui/components/sheet';
import { MarkdownEditor } from '@workspace/ui/custom-components/editor'; import { MarkdownEditor } from '@workspace/ui/custom-components/editor';
import { Icon } from '@workspace/ui/custom-components/icon';
import { TagInput } from '@workspace/ui/custom-components/tag-input'; import { TagInput } from '@workspace/ui/custom-components/tag-input';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';

View File

@ -1,7 +1,6 @@
'use client'; 'use client';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { import {
Form, Form,
@ -21,6 +20,7 @@ import {
SheetTrigger, SheetTrigger,
} from '@workspace/ui/components/sheet'; } from '@workspace/ui/components/sheet';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input'; import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';

View File

@ -2,7 +2,6 @@
import { getNodeGroupList } from '@/services/admin/server'; import { getNodeGroupList } from '@/services/admin/server';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card'; import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card';
@ -35,6 +34,7 @@ import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
import { Combobox } from '@workspace/ui/custom-components/combobox'; import { Combobox } from '@workspace/ui/custom-components/combobox';
import { ArrayInput } from '@workspace/ui/custom-components/dynamic-Inputs'; import { ArrayInput } from '@workspace/ui/custom-components/dynamic-Inputs';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input'; import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { Icon } from '@workspace/ui/custom-components/icon';
import TagInput from '@workspace/ui/custom-components/tag-input'; import TagInput from '@workspace/ui/custom-components/tag-input';
import { cn } from '@workspace/ui/lib/utils'; import { cn } from '@workspace/ui/lib/utils';
import { unitConversion } from '@workspace/ui/utils'; import { unitConversion } from '@workspace/ui/utils';

View File

@ -7,7 +7,6 @@ import {
getTicketList, getTicketList,
updateTicketStatus, updateTicketStatus,
} from '@/services/admin/ticket'; } from '@/services/admin/ticket';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { import {
@ -22,6 +21,7 @@ import { Input } from '@workspace/ui/components/input';
import { Label } from '@workspace/ui/components/label'; import { Label } from '@workspace/ui/components/label';
import { ScrollArea } from '@workspace/ui/components/scroll-area'; import { ScrollArea } from '@workspace/ui/components/scroll-area';
import { ConfirmButton } from '@workspace/ui/custom-components/confirm-button'; import { ConfirmButton } from '@workspace/ui/custom-components/confirm-button';
import { Icon } from '@workspace/ui/custom-components/icon';
import { cn } from '@workspace/ui/lib/utils'; import { cn } from '@workspace/ui/lib/utils';
import { formatDate } from '@workspace/ui/utils'; import { formatDate } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';

View File

@ -1,7 +1,6 @@
'use client'; 'use client';
import { getSystemLog, restartSystem } from '@/services/admin/tool'; import { getSystemLog, restartSystem } from '@/services/admin/tool';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { import {
Accordion, Accordion,
@ -30,6 +29,7 @@ import {
CardTitle, CardTitle,
} from '@workspace/ui/components/card'; } from '@workspace/ui/components/card';
import { ScrollArea } from '@workspace/ui/components/scroll-area'; import { ScrollArea } from '@workspace/ui/components/scroll-area';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { useState } from 'react'; import { useState } from 'react';

View File

@ -2,7 +2,6 @@
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { import {
Form, Form,
@ -24,6 +23,7 @@ import {
import { Switch } from '@workspace/ui/components/switch'; import { Switch } from '@workspace/ui/components/switch';
import { AreaCodeSelect } from '@workspace/ui/custom-components/area-code-select'; import { AreaCodeSelect } from '@workspace/ui/custom-components/area-code-select';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input'; import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { unitConversion } from '@workspace/ui/utils'; import { unitConversion } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';

View File

@ -1,7 +1,6 @@
'use client'; 'use client';
import { queryServerTotalData, queryTicketWaitReply } from '@/services/admin/console'; import { queryServerTotalData, queryTicketWaitReply } from '@/services/admin/console';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card'; import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card';
import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@workspace/ui/components/chart'; import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@workspace/ui/components/chart';
@ -13,6 +12,7 @@ import {
SelectValue, SelectValue,
} from '@workspace/ui/components/select'; } from '@workspace/ui/components/select';
import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs'; import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
import { Icon } from '@workspace/ui/custom-components/icon';
import { formatBytes } from '@workspace/ui/utils'; import { formatBytes } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import Link from 'next/link'; import Link from 'next/link';

View File

@ -2,7 +2,6 @@
import { locales } from '@/config/constants'; import { locales } from '@/config/constants';
import { setLocale } from '@/utils/common'; import { setLocale } from '@/utils/common';
import { Icon } from '@iconify/react';
import { import {
Select, Select,
SelectContent, SelectContent,
@ -10,6 +9,7 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from '@workspace/ui/components/select'; } from '@workspace/ui/components/select';
import { Icon } from '@workspace/ui/custom-components/icon';
import { getCountry } from '@workspace/ui/utils'; import { getCountry } from '@workspace/ui/utils';
import { useLocale, useTranslations } from 'next-intl'; import { useLocale, useTranslations } from 'next-intl';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';

View File

@ -1,7 +1,6 @@
'use client'; 'use client';
import { navs } from '@/config/navs'; import { navs } from '@/config/navs';
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { Icon } from '@iconify/react';
import { import {
Sidebar, Sidebar,
SidebarContent, SidebarContent,
@ -13,6 +12,7 @@ import {
SidebarMenuButton, SidebarMenuButton,
SidebarMenuItem, SidebarMenuItem,
} from '@workspace/ui/components/sidebar'; } from '@workspace/ui/components/sidebar';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import Image from 'next/legacy/image'; import Image from 'next/legacy/image';
import Link from 'next/link'; import Link from 'next/link';

View File

@ -1,24 +1,39 @@
{ {
"actions": "akce", "actions": "akce",
"app": { "app": {
"add": "Přidat",
"appDownloadURL": "URL pro stažení aplikace", "appDownloadURL": "URL pro stažení aplikace",
"appIcon": "Ikona aplikace", "appIcon": "Ikona aplikace",
"appList": "Seznam aplikací",
"appName": "Název aplikace", "appName": "Název aplikace",
"backupDomains": "Seznam záložních domén",
"backupDomainsDescription": "Seznam záložních domén pro řešení domén, jedna doména na řádek",
"batchDelete": "Hromadné smazání", "batchDelete": "Hromadné smazání",
"cancel": "Zrušit", "cancel": "Zrušit",
"config": "Konfigurace",
"configApp": "Konfigurace aplikace",
"confirm": "Potvrdit", "confirm": "Potvrdit",
"confirmDelete": "Potvrdit smazání", "confirmDelete": "Potvrdit smazání",
"create": "Vytvořit",
"createApp": "Vytvořit aplikaci", "createApp": "Vytvořit aplikaci",
"createSuccess": "Úspěšně vytvořeno", "createSuccess": "Úspěšně vytvořeno",
"defaultVersion": "Výchozí",
"delete": "Smazat", "delete": "Smazat",
"deleteSuccess": "Úspěšně smazáno",
"deleteWarning": "Tuto akci nelze vrátit zpět", "deleteWarning": "Tuto akci nelze vrátit zpět",
"describeDescription": "Používá se k popisu aplikace, zobrazuje se v seznamu aplikací",
"description": "Popis",
"downloadLink": "Odkaz ke stažení",
"edit": "Upravit", "edit": "Upravit",
"editApp": "Upravit aplikaci", "editApp": "Upravit aplikaci",
"nameDescription": "Název aplikace, zobrazuje se v seznamu aplikací",
"platform": "Platforma", "platform": "Platforma",
"startupPicture": "Úvodní obrázek",
"startupPictureDescription": "Úvodní obrázek, podporuje síťové a lokální obrázky. Pro síťové obrázky zadejte úplnou URL adresu obrázku",
"startupPicturePreview": "Náhled úvodního obrázku",
"startupPictureSkip": "Čas přeskočení úvodního obrázku",
"startupPictureSkipDescription": "Doba zobrazení úvodního obrázku v sekundách, zadejte 0 pro nezobrazení",
"subscriptionProtocol": "Protokol předplatného", "subscriptionProtocol": "Protokol předplatného",
"updateSuccess": "Úspěšně aktualizováno" "updateSuccess": "Úspěšně aktualizováno",
"version": "Verze"
}, },
"cancel": "Zrušit", "cancel": "Zrušit",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "Aktionen", "actions": "Aktionen",
"app": { "app": {
"add": "Hinzufügen",
"appDownloadURL": "App-Download-URL", "appDownloadURL": "App-Download-URL",
"appIcon": "App-Symbol", "appIcon": "App-Symbol",
"appList": "App-Liste",
"appName": "App-Name", "appName": "App-Name",
"backupDomains": "Liste der Backup-Domains",
"backupDomainsDescription": "Liste der Backup-Domains für die Domain-Auflösung, eine Domain pro Zeile",
"batchDelete": "Stapel löschen", "batchDelete": "Stapel löschen",
"cancel": "Abbrechen", "cancel": "Abbrechen",
"config": "Konfiguration",
"configApp": "App-Konfiguration",
"confirm": "Bestätigen", "confirm": "Bestätigen",
"confirmDelete": "Löschen bestätigen", "confirmDelete": "Löschen bestätigen",
"create": "Erstellen",
"createApp": "App erstellen", "createApp": "App erstellen",
"createSuccess": "Erfolgreich erstellt", "createSuccess": "Erfolgreich erstellt",
"defaultVersion": "Standard",
"delete": "Löschen", "delete": "Löschen",
"deleteSuccess": "Erfolgreich gelöscht",
"deleteWarning": "Diese Aktion kann nicht rückgängig gemacht werden", "deleteWarning": "Diese Aktion kann nicht rückgängig gemacht werden",
"describeDescription": "Wird verwendet, um die Anwendung zu beschreiben, wird in der App-Liste angezeigt",
"description": "Beschreibung",
"downloadLink": "Download-Link",
"edit": "Bearbeiten", "edit": "Bearbeiten",
"editApp": "App bearbeiten", "editApp": "App bearbeiten",
"nameDescription": "Anwendungsname, wird in der App-Liste angezeigt",
"platform": "Plattform", "platform": "Plattform",
"startupPicture": "Startbild",
"startupPictureDescription": "Startbild, unterstützt Netzwerk- und lokale Bilder. Für Netzwerkbilder bitte die vollständige Bild-URL eingeben",
"startupPicturePreview": "Vorschau des Startbildes",
"startupPictureSkip": "Überspringzeit des Startbildes",
"startupPictureSkipDescription": "Anzeigedauer des Startbildes in Sekunden, 0 eingeben, um nicht anzuzeigen",
"subscriptionProtocol": "Abonnementprotokoll", "subscriptionProtocol": "Abonnementprotokoll",
"updateSuccess": "Erfolgreich aktualisiert" "updateSuccess": "Erfolgreich aktualisiert",
"version": "Version"
}, },
"cancel": "Abbrechen", "cancel": "Abbrechen",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "Actions", "actions": "Actions",
"app": { "app": {
"add": "Add",
"appDownloadURL": "App Download URL", "appDownloadURL": "App Download URL",
"appIcon": "App Icon", "appIcon": "App Icon",
"appList": "App List",
"appName": "App Name", "appName": "App Name",
"backupDomains": "Backup Domain List",
"backupDomainsDescription": "Backup domain list for domain resolution, one domain per line",
"batchDelete": "Batch Delete", "batchDelete": "Batch Delete",
"cancel": "Cancel", "cancel": "Cancel",
"config": "Config",
"configApp": "App Configuration",
"confirm": "Confirm", "confirm": "Confirm",
"confirmDelete": "Confirm Delete", "confirmDelete": "Are you sure you want to delete?",
"create": "Create",
"createApp": "Create App", "createApp": "Create App",
"createSuccess": "Created successfully", "createSuccess": "Created successfully",
"defaultVersion": "Default",
"delete": "Delete", "delete": "Delete",
"deleteSuccess": "Deleted successfully", "deleteWarning": "Data cannot be recovered after deletion. Please proceed with caution.",
"deleteWarning": "This action cannot be undone", "describeDescription": "Used to describe the application, displayed in the app list",
"description": "Description",
"downloadLink": "Download Link",
"edit": "Edit", "edit": "Edit",
"editApp": "Edit App", "editApp": "Edit App",
"nameDescription": "Application name, displayed in the app list",
"platform": "Platform", "platform": "Platform",
"startupPicture": "Startup Picture",
"startupPictureDescription": "Startup picture, supports network and local images. For network images, please enter the complete image URL",
"startupPicturePreview": "Startup Picture Preview",
"startupPictureSkip": "Startup Picture Skip Time",
"startupPictureSkipDescription": "Startup picture display time in seconds, enter 0 to not display",
"subscriptionProtocol": "Subscription Protocol", "subscriptionProtocol": "Subscription Protocol",
"updateSuccess": "Updated successfully" "updateSuccess": "Updated successfully",
"version": "Version"
}, },
"cancel": "Cancel", "cancel": "Cancel",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "acciones", "actions": "acciones",
"app": { "app": {
"add": "Agregar",
"appDownloadURL": "URL de Descarga de la App", "appDownloadURL": "URL de Descarga de la App",
"appIcon": "Icono de la App", "appIcon": "Icono de la App",
"appList": "Lista de Aplicaciones",
"appName": "Nombre de la App", "appName": "Nombre de la App",
"backupDomains": "Lista de Dominios de Respaldo",
"backupDomainsDescription": "Lista de dominios de respaldo para la resolución de dominios, un dominio por línea",
"batchDelete": "Eliminar en Lote", "batchDelete": "Eliminar en Lote",
"cancel": "Cancelar", "cancel": "Cancelar",
"config": "Configuración",
"configApp": "Configuración de la Aplicación",
"confirm": "Confirmar", "confirm": "Confirmar",
"confirmDelete": "Confirmar Eliminación", "confirmDelete": "Confirmar Eliminación",
"create": "Crear",
"createApp": "Crear App", "createApp": "Crear App",
"createSuccess": "Creado con éxito", "createSuccess": "Creado con éxito",
"defaultVersion": "Versión Predeterminada",
"delete": "Eliminar", "delete": "Eliminar",
"deleteSuccess": "Eliminado con éxito",
"deleteWarning": "Esta acción no se puede deshacer", "deleteWarning": "Esta acción no se puede deshacer",
"describeDescription": "Se utiliza para describir la aplicación, se muestra en la lista de aplicaciones",
"description": "Descripción",
"downloadLink": "Enlace de Descarga",
"edit": "Editar", "edit": "Editar",
"editApp": "Editar App", "editApp": "Editar App",
"nameDescription": "Nombre de la aplicación, se muestra en la lista de aplicaciones",
"platform": "Plataforma", "platform": "Plataforma",
"startupPicture": "Imagen de Inicio",
"startupPictureDescription": "Imagen de inicio, admite imágenes de red y locales. Para imágenes de red, ingrese la URL completa de la imagen",
"startupPicturePreview": "Vista Previa de la Imagen de Inicio",
"startupPictureSkip": "Tiempo de Salto de la Imagen de Inicio",
"startupPictureSkipDescription": "Tiempo de visualización de la imagen de inicio en segundos, ingrese 0 para no mostrar",
"subscriptionProtocol": "Protocolo de Suscripción", "subscriptionProtocol": "Protocolo de Suscripción",
"updateSuccess": "Actualizado con éxito" "updateSuccess": "Actualizado con éxito",
"version": "Versión"
}, },
"cancel": "Cancelar", "cancel": "Cancelar",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "acciones", "actions": "acciones",
"app": { "app": {
"add": "Agregar",
"appDownloadURL": "URL de Descarga de la App", "appDownloadURL": "URL de Descarga de la App",
"appIcon": "Ícono de la App", "appIcon": "Ícono de la App",
"appList": "Lista de Aplicaciones",
"appName": "Nombre de la App", "appName": "Nombre de la App",
"backupDomains": "Lista de Dominios de Respaldo",
"backupDomainsDescription": "Lista de dominios de respaldo para la resolución de dominios, un dominio por línea",
"batchDelete": "Eliminar en Lote", "batchDelete": "Eliminar en Lote",
"cancel": "Cancelar", "cancel": "Cancelar",
"config": "Configuración",
"configApp": "Configuración de la Aplicación",
"confirm": "Confirmar", "confirm": "Confirmar",
"confirmDelete": "Confirmar Eliminación", "confirmDelete": "Confirmar Eliminación",
"create": "Crear",
"createApp": "Crear App", "createApp": "Crear App",
"createSuccess": "Creado exitosamente", "createSuccess": "Creado exitosamente",
"defaultVersion": "Versión Predeterminada",
"delete": "Eliminar", "delete": "Eliminar",
"deleteSuccess": "Eliminado exitosamente",
"deleteWarning": "Esta acción no se puede deshacer", "deleteWarning": "Esta acción no se puede deshacer",
"describeDescription": "Se utiliza para describir la aplicación, se muestra en la lista de aplicaciones",
"description": "Descripción",
"downloadLink": "Enlace de Descarga",
"edit": "Editar", "edit": "Editar",
"editApp": "Editar App", "editApp": "Editar App",
"nameDescription": "Nombre de la aplicación, se muestra en la lista de aplicaciones",
"platform": "Plataforma", "platform": "Plataforma",
"startupPicture": "Imagen de Inicio",
"startupPictureDescription": "Imagen de inicio, admite imágenes de red y locales. Para imágenes de red, ingrese la URL completa de la imagen",
"startupPicturePreview": "Vista Previa de la Imagen de Inicio",
"startupPictureSkip": "Tiempo de Salto de la Imagen de Inicio",
"startupPictureSkipDescription": "Tiempo de visualización de la imagen de inicio en segundos, ingrese 0 para no mostrar",
"subscriptionProtocol": "Protocolo de Suscripción", "subscriptionProtocol": "Protocolo de Suscripción",
"updateSuccess": "Actualizado exitosamente" "updateSuccess": "Actualizado exitosamente",
"version": "Versión"
}, },
"cancel": "Cancelar", "cancel": "Cancelar",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "اقدامات", "actions": "اقدامات",
"app": { "app": {
"add": "افزودن",
"appDownloadURL": "آدرس دانلود اپلیکیشن", "appDownloadURL": "آدرس دانلود اپلیکیشن",
"appIcon": "آیکون اپلیکیشن", "appIcon": "آیکون اپلیکیشن",
"appList": "لیست برنامه‌ها",
"appName": "نام اپلیکیشن", "appName": "نام اپلیکیشن",
"backupDomains": "لیست دامنه‌های پشتیبان",
"backupDomainsDescription": "لیست دامنه‌های پشتیبان برای حل دامنه، هر دامنه در یک خط",
"batchDelete": "حذف گروهی", "batchDelete": "حذف گروهی",
"cancel": "لغو", "cancel": "لغو",
"config": "پیکربندی",
"configApp": "پیکربندی برنامه",
"confirm": "تأیید", "confirm": "تأیید",
"confirmDelete": "تأیید حذف", "confirmDelete": "تأیید حذف",
"create": "ایجاد",
"createApp": "ایجاد اپلیکیشن", "createApp": "ایجاد اپلیکیشن",
"createSuccess": "با موفقیت ایجاد شد", "createSuccess": "با موفقیت ایجاد شد",
"defaultVersion": "پیش‌فرض",
"delete": "حذف", "delete": "حذف",
"deleteSuccess": "با موفقیت حذف شد",
"deleteWarning": "این عمل قابل بازگشت نیست", "deleteWarning": "این عمل قابل بازگشت نیست",
"describeDescription": "برای توصیف برنامه استفاده می‌شود، در لیست برنامه‌ها نمایش داده می‌شود",
"description": "توضیحات",
"downloadLink": "لینک دانلود",
"edit": "ویرایش", "edit": "ویرایش",
"editApp": "ویرایش اپلیکیشن", "editApp": "ویرایش اپلیکیشن",
"nameDescription": "نام برنامه، در لیست برنامه‌ها نمایش داده می‌شود",
"platform": "پلتفرم", "platform": "پلتفرم",
"startupPicture": "تصویر شروع",
"startupPictureDescription": "تصویر شروع، از تصاویر شبکه و محلی پشتیبانی می‌کند. برای تصاویر شبکه، لطفاً آدرس کامل تصویر را وارد کنید",
"startupPicturePreview": "پیش‌نمایش تصویر شروع",
"startupPictureSkip": "زمان عبور از تصویر شروع",
"startupPictureSkipDescription": "زمان نمایش تصویر شروع به ثانیه، برای عدم نمایش 0 وارد کنید",
"subscriptionProtocol": "پروتکل اشتراک", "subscriptionProtocol": "پروتکل اشتراک",
"updateSuccess": "با موفقیت به‌روزرسانی شد" "updateSuccess": "با موفقیت به‌روزرسانی شد",
"version": "نسخه"
}, },
"cancel": "لغو", "cancel": "لغو",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "toiminnot", "actions": "toiminnot",
"app": { "app": {
"add": "Lisää",
"appDownloadURL": "Sovelluksen lataus-URL", "appDownloadURL": "Sovelluksen lataus-URL",
"appIcon": "Sovelluksen kuvake", "appIcon": "Sovelluksen kuvake",
"appList": "Sovellusluettelo",
"appName": "Sovelluksen nimi", "appName": "Sovelluksen nimi",
"backupDomains": "Varmuuskopiodomainien luettelo",
"backupDomainsDescription": "Varmuuskopiodomainien luettelo domainin resoluutiota varten, yksi domain per rivi",
"batchDelete": "Poista erä", "batchDelete": "Poista erä",
"cancel": "Peruuta", "cancel": "Peruuta",
"config": "Asetukset",
"configApp": "Sovelluksen asetukset",
"confirm": "Vahvista", "confirm": "Vahvista",
"confirmDelete": "Vahvista poisto", "confirmDelete": "Vahvista poisto",
"create": "Luo",
"createApp": "Luo sovellus", "createApp": "Luo sovellus",
"createSuccess": "Luotu onnistuneesti", "createSuccess": "Luotu onnistuneesti",
"defaultVersion": "Oletus",
"delete": "Poista", "delete": "Poista",
"deleteSuccess": "Poistettu onnistuneesti",
"deleteWarning": "Tätä toimintoa ei voi peruuttaa", "deleteWarning": "Tätä toimintoa ei voi peruuttaa",
"describeDescription": "Käytetään sovelluksen kuvaamiseen, näytetään sovellusluettelossa",
"description": "Kuvaus",
"downloadLink": "Latauslinkki",
"edit": "Muokkaa", "edit": "Muokkaa",
"editApp": "Muokkaa sovellusta", "editApp": "Muokkaa sovellusta",
"nameDescription": "Sovelluksen nimi, näytetään sovellusluettelossa",
"platform": "Alusta", "platform": "Alusta",
"startupPicture": "Käynnistyskuva",
"startupPictureDescription": "Käynnistyskuva, tukee verkko- ja paikallisia kuvia. Verkkokuville, syötä täydellinen kuvan URL-osoite",
"startupPicturePreview": "Käynnistyskuvan esikatselu",
"startupPictureSkip": "Käynnistyskuvan ohitusaika",
"startupPictureSkipDescription": "Käynnistyskuvan näyttöaika sekunteina, syötä 0, jos ei näytetä",
"subscriptionProtocol": "Tilausprotokolla", "subscriptionProtocol": "Tilausprotokolla",
"updateSuccess": "Päivitetty onnistuneesti" "updateSuccess": "Päivitetty onnistuneesti",
"version": "Versio"
}, },
"cancel": "Peruuta", "cancel": "Peruuta",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "actions", "actions": "actions",
"app": { "app": {
"add": "Ajouter",
"appDownloadURL": "URL de téléchargement de l'application", "appDownloadURL": "URL de téléchargement de l'application",
"appIcon": "Icône de l'application", "appIcon": "Icône de l'application",
"appList": "Liste des applications",
"appName": "Nom de l'application", "appName": "Nom de l'application",
"backupDomains": "Liste des domaines de sauvegarde",
"backupDomainsDescription": "Liste des domaines de sauvegarde pour la résolution de domaine, un domaine par ligne",
"batchDelete": "Suppression par lot", "batchDelete": "Suppression par lot",
"cancel": "Annuler", "cancel": "Annuler",
"config": "Configuration",
"configApp": "Configuration de l'application",
"confirm": "Confirmer", "confirm": "Confirmer",
"confirmDelete": "Confirmer la suppression", "confirmDelete": "Confirmer la suppression",
"create": "Créer",
"createApp": "Créer une application", "createApp": "Créer une application",
"createSuccess": "Créé avec succès", "createSuccess": "Créé avec succès",
"defaultVersion": "Par défaut",
"delete": "Supprimer", "delete": "Supprimer",
"deleteSuccess": "Supprimé avec succès",
"deleteWarning": "Cette action est irréversible", "deleteWarning": "Cette action est irréversible",
"describeDescription": "Utilisé pour décrire l'application, affiché dans la liste des applications",
"description": "Description",
"downloadLink": "Lien de téléchargement",
"edit": "Modifier", "edit": "Modifier",
"editApp": "Modifier l'application", "editApp": "Modifier l'application",
"nameDescription": "Nom de l'application, affiché dans la liste des applications",
"platform": "Plateforme", "platform": "Plateforme",
"startupPicture": "Image de démarrage",
"startupPictureDescription": "Image de démarrage, prend en charge les images réseau et locales. Pour les images réseau, veuillez entrer l'URL complète de l'image",
"startupPicturePreview": "Aperçu de l'image de démarrage",
"startupPictureSkip": "Temps de saut de l'image de démarrage",
"startupPictureSkipDescription": "Temps d'affichage de l'image de démarrage en secondes, entrez 0 pour ne pas afficher",
"subscriptionProtocol": "Protocole d'abonnement", "subscriptionProtocol": "Protocole d'abonnement",
"updateSuccess": "Mis à jour avec succès" "updateSuccess": "Mis à jour avec succès",
"version": "Version"
}, },
"cancel": "Annuler", "cancel": "Annuler",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "क्रियाएँ", "actions": "क्रियाएँ",
"app": { "app": {
"add": "जोड़ें",
"appDownloadURL": "ऐप डाउनलोड URL", "appDownloadURL": "ऐप डाउनलोड URL",
"appIcon": "ऐप आइकन", "appIcon": "ऐप आइकन",
"appList": "ऐप सूची",
"appName": "ऐप का नाम", "appName": "ऐप का नाम",
"backupDomains": "बैकअप डोमेन सूची",
"backupDomainsDescription": "डोमेन समाधान के लिए बैकअप डोमेन सूची, प्रत्येक पंक्ति में एक डोमेन",
"batchDelete": "बैच हटाएं", "batchDelete": "बैच हटाएं",
"cancel": "रद्द करें", "cancel": "रद्द करें",
"config": "कॉन्फ़िग",
"configApp": "ऐप कॉन्फ़िगरेशन",
"confirm": "पुष्टि करें", "confirm": "पुष्टि करें",
"confirmDelete": "हटाने की पुष्टि करें", "confirmDelete": "हटाने की पुष्टि करें",
"create": "बनाएं",
"createApp": "ऐप बनाएं", "createApp": "ऐप बनाएं",
"createSuccess": "सफलतापूर्वक बनाया गया", "createSuccess": "सफलतापूर्वक बनाया गया",
"defaultVersion": "डिफ़ॉल्ट",
"delete": "हटाएं", "delete": "हटाएं",
"deleteSuccess": "सफलतापूर्वक हटाया गया",
"deleteWarning": "यह क्रिया पूर्ववत नहीं की जा सकती", "deleteWarning": "यह क्रिया पूर्ववत नहीं की जा सकती",
"describeDescription": "एप्लिकेशन का वर्णन करने के लिए उपयोग किया जाता है, ऐप सूची में प्रदर्शित",
"description": "विवरण",
"downloadLink": "डाउनलोड लिंक",
"edit": "संपादित करें", "edit": "संपादित करें",
"editApp": "ऐप संपादित करें", "editApp": "ऐप संपादित करें",
"nameDescription": "एप्लिकेशन का नाम, ऐप सूची में प्रदर्शित",
"platform": "प्लेटफ़ॉर्म", "platform": "प्लेटफ़ॉर्म",
"startupPicture": "स्टार्टअप चित्र",
"startupPictureDescription": "स्टार्टअप चित्र, नेटवर्क और स्थानीय छवियों का समर्थन करता है। नेटवर्क छवियों के लिए, कृपया पूरी छवि URL दर्ज करें",
"startupPicturePreview": "स्टार्टअप चित्र पूर्वावलोकन",
"startupPictureSkip": "स्टार्टअप चित्र छोड़ने का समय",
"startupPictureSkipDescription": "स्टार्टअप चित्र प्रदर्शन समय सेकंड में, प्रदर्शित न करने के लिए 0 दर्ज करें",
"subscriptionProtocol": "सदस्यता प्रोटोकॉल", "subscriptionProtocol": "सदस्यता प्रोटोकॉल",
"updateSuccess": "सफलतापूर्वक अपडेट किया गया" "updateSuccess": "सफलतापूर्वक अपडेट किया गया",
"version": "संस्करण"
}, },
"cancel": "रद्द करें", "cancel": "रद्द करें",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "műveletek", "actions": "műveletek",
"app": { "app": {
"add": "Hozzáadás",
"appDownloadURL": "Alkalmazás letöltési URL", "appDownloadURL": "Alkalmazás letöltési URL",
"appIcon": "Alkalmazás ikon", "appIcon": "Alkalmazás ikon",
"appList": "Alkalmazáslista",
"appName": "Alkalmazás neve", "appName": "Alkalmazás neve",
"backupDomains": "Biztonsági tartománylista",
"backupDomainsDescription": "Biztonsági tartománylista a tartomány feloldásához, soronként egy tartomány",
"batchDelete": "Csoportos törlés", "batchDelete": "Csoportos törlés",
"cancel": "Mégse", "cancel": "Mégse",
"config": "Beállítás",
"configApp": "Alkalmazás beállítása",
"confirm": "Megerősítés", "confirm": "Megerősítés",
"confirmDelete": "Törlés megerősítése", "confirmDelete": "Törlés megerősítése",
"create": "Létrehozás",
"createApp": "Alkalmazás létrehozása", "createApp": "Alkalmazás létrehozása",
"createSuccess": "Sikeresen létrehozva", "createSuccess": "Sikeresen létrehozva",
"defaultVersion": "Alapértelmezett",
"delete": "Törlés", "delete": "Törlés",
"deleteSuccess": "Sikeresen törölve",
"deleteWarning": "Ez a művelet nem vonható vissza", "deleteWarning": "Ez a művelet nem vonható vissza",
"describeDescription": "Az alkalmazás leírására szolgál, megjelenik az alkalmazáslistában",
"description": "Leírás",
"downloadLink": "Letöltési hivatkozás",
"edit": "Szerkesztés", "edit": "Szerkesztés",
"editApp": "Alkalmazás szerkesztése", "editApp": "Alkalmazás szerkesztése",
"nameDescription": "Alkalmazás neve, megjelenik az alkalmazáslistában",
"platform": "Platform", "platform": "Platform",
"startupPicture": "Indító kép",
"startupPictureDescription": "Indító kép, támogatja a hálózati és helyi képeket. Hálózati képek esetén kérjük, adja meg a teljes kép URL-jét",
"startupPicturePreview": "Indító kép előnézete",
"startupPictureSkip": "Indító kép kihagyási ideje",
"startupPictureSkipDescription": "Indító kép megjelenítési ideje másodpercben, 0 megadása esetén nem jelenik meg",
"subscriptionProtocol": "Előfizetési protokoll", "subscriptionProtocol": "Előfizetési protokoll",
"updateSuccess": "Sikeresen frissítve" "updateSuccess": "Sikeresen frissítve",
"version": "Verzió"
}, },
"cancel": "Mégse", "cancel": "Mégse",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "アクション", "actions": "アクション",
"app": { "app": {
"add": "追加",
"appDownloadURL": "アプリダウンロードURL", "appDownloadURL": "アプリダウンロードURL",
"appIcon": "アプリアイコン", "appIcon": "アプリアイコン",
"appList": "アプリリスト",
"appName": "アプリ名", "appName": "アプリ名",
"backupDomains": "バックアップドメインリスト",
"backupDomainsDescription": "ドメイン解決のためのバックアップドメインリスト、1行に1つのドメイン",
"batchDelete": "一括削除", "batchDelete": "一括削除",
"cancel": "キャンセル", "cancel": "キャンセル",
"config": "設定",
"configApp": "アプリ設定",
"confirm": "確認", "confirm": "確認",
"confirmDelete": "削除を確認", "confirmDelete": "削除を確認",
"create": "作成",
"createApp": "アプリ作成", "createApp": "アプリ作成",
"createSuccess": "作成に成功しました", "createSuccess": "作成に成功しました",
"defaultVersion": "デフォルト",
"delete": "削除", "delete": "削除",
"deleteSuccess": "削除に成功しました",
"deleteWarning": "この操作は元に戻せません", "deleteWarning": "この操作は元に戻せません",
"describeDescription": "アプリケーションを説明するために使用され、アプリリストに表示されます",
"description": "説明",
"downloadLink": "ダウンロードリンク",
"edit": "編集", "edit": "編集",
"editApp": "アプリ編集", "editApp": "アプリ編集",
"nameDescription": "アプリケーション名、アプリリストに表示されます",
"platform": "プラットフォーム", "platform": "プラットフォーム",
"startupPicture": "スタートアップ画像",
"startupPictureDescription": "スタートアップ画像、ネットワークおよびローカル画像をサポートします。ネットワーク画像の場合は、完全な画像URLを入力してください",
"startupPicturePreview": "スタートアップ画像プレビュー",
"startupPictureSkip": "スタートアップ画像スキップ時間",
"startupPictureSkipDescription": "スタートアップ画像の表示時間、表示しない場合は0を入力",
"subscriptionProtocol": "サブスクリプションプロトコル", "subscriptionProtocol": "サブスクリプションプロトコル",
"updateSuccess": "更新に成功しました" "updateSuccess": "更新に成功しました",
"version": "バージョン"
}, },
"cancel": "キャンセル", "cancel": "キャンセル",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "작업", "actions": "작업",
"app": { "app": {
"add": "추가",
"appDownloadURL": "앱 다운로드 URL", "appDownloadURL": "앱 다운로드 URL",
"appIcon": "앱 아이콘", "appIcon": "앱 아이콘",
"appList": "앱 목록",
"appName": "앱 이름", "appName": "앱 이름",
"backupDomains": "백업 도메인 목록",
"backupDomainsDescription": "도메인 해석을 위한 백업 도메인 목록, 한 줄에 하나의 도메인",
"batchDelete": "일괄 삭제", "batchDelete": "일괄 삭제",
"cancel": "취소", "cancel": "취소",
"config": "설정",
"configApp": "앱 설정",
"confirm": "확인", "confirm": "확인",
"confirmDelete": "삭제 확인", "confirmDelete": "삭제 확인",
"create": "생성",
"createApp": "앱 생성", "createApp": "앱 생성",
"createSuccess": "성공적으로 생성되었습니다", "createSuccess": "성공적으로 생성되었습니다",
"defaultVersion": "기본",
"delete": "삭제", "delete": "삭제",
"deleteSuccess": "성공적으로 삭제되었습니다",
"deleteWarning": "이 작업은 되돌릴 수 없습니다", "deleteWarning": "이 작업은 되돌릴 수 없습니다",
"describeDescription": "애플리케이션을 설명하는 데 사용되며, 앱 목록에 표시됩니다",
"description": "설명",
"downloadLink": "다운로드 링크",
"edit": "편집", "edit": "편집",
"editApp": "앱 편집", "editApp": "앱 편집",
"nameDescription": "애플리케이션 이름, 앱 목록에 표시됩니다",
"platform": "플랫폼", "platform": "플랫폼",
"startupPicture": "시작 화면",
"startupPictureDescription": "시작 화면, 네트워크 및 로컬 이미지를 지원합니다. 네트워크 이미지를 사용할 경우, 전체 이미지 URL을 입력하세요",
"startupPicturePreview": "시작 화면 미리보기",
"startupPictureSkip": "시작 화면 건너뛰기 시간",
"startupPictureSkipDescription": "시작 화면 표시 시간(초), 0을 입력하면 표시되지 않습니다",
"subscriptionProtocol": "구독 프로토콜", "subscriptionProtocol": "구독 프로토콜",
"updateSuccess": "성공적으로 업데이트되었습니다" "updateSuccess": "성공적으로 업데이트되었습니다",
"version": "버전"
}, },
"cancel": "취소", "cancel": "취소",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "handlinger", "actions": "handlinger",
"app": { "app": {
"add": "Legg til",
"appDownloadURL": "App Nedlastings-URL", "appDownloadURL": "App Nedlastings-URL",
"appIcon": "App-ikon", "appIcon": "App-ikon",
"appList": "Appliste",
"appName": "App-navn", "appName": "App-navn",
"backupDomains": "Sikkerhetskopidomener",
"backupDomainsDescription": "Liste over sikkerhetskopidomener for domeneresolusjon, ett domene per linje",
"batchDelete": "Slett i gruppe", "batchDelete": "Slett i gruppe",
"cancel": "Avbryt", "cancel": "Avbryt",
"config": "Konfigurasjon",
"configApp": "Appkonfigurasjon",
"confirm": "Bekreft", "confirm": "Bekreft",
"confirmDelete": "Bekreft sletting", "confirmDelete": "Bekreft sletting",
"create": "Opprett",
"createApp": "Opprett app", "createApp": "Opprett app",
"createSuccess": "Opprettet vellykket", "createSuccess": "Opprettet vellykket",
"defaultVersion": "Standard",
"delete": "Slett", "delete": "Slett",
"deleteSuccess": "Slettet vellykket",
"deleteWarning": "Denne handlingen kan ikke angres", "deleteWarning": "Denne handlingen kan ikke angres",
"describeDescription": "Brukes til å beskrive applikasjonen, vises i applisten",
"description": "Beskrivelse",
"downloadLink": "Nedlastingslenke",
"edit": "Rediger", "edit": "Rediger",
"editApp": "Rediger app", "editApp": "Rediger app",
"nameDescription": "Applikasjonsnavn, vises i applisten",
"platform": "Plattform", "platform": "Plattform",
"startupPicture": "Oppstartsbilde",
"startupPictureDescription": "Oppstartsbilde, støtter nettverks- og lokale bilder. For nettverksbilder, vennligst skriv inn den fullstendige bilde-URLen",
"startupPicturePreview": "Forhåndsvisning av oppstartsbilde",
"startupPictureSkip": "Tid for å hoppe over oppstartsbilde",
"startupPictureSkipDescription": "Visningstid for oppstartsbilde i sekunder, skriv inn 0 for å ikke vise",
"subscriptionProtocol": "Abonnementsprotokoll", "subscriptionProtocol": "Abonnementsprotokoll",
"updateSuccess": "Oppdatert vellykket" "updateSuccess": "Oppdatert vellykket",
"version": "Versjon"
}, },
"cancel": "Avbryt", "cancel": "Avbryt",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "działania", "actions": "działania",
"app": { "app": {
"add": "Dodaj",
"appDownloadURL": "URL pobierania aplikacji", "appDownloadURL": "URL pobierania aplikacji",
"appIcon": "Ikona aplikacji", "appIcon": "Ikona aplikacji",
"appList": "Lista aplikacji",
"appName": "Nazwa aplikacji", "appName": "Nazwa aplikacji",
"backupDomains": "Lista domen zapasowych",
"backupDomainsDescription": "Lista domen zapasowych do rozwiązywania domen, jedna domena na linię",
"batchDelete": "Usuń zbiorczo", "batchDelete": "Usuń zbiorczo",
"cancel": "Anuluj", "cancel": "Anuluj",
"config": "Konfiguracja",
"configApp": "Konfiguracja aplikacji",
"confirm": "Potwierdź", "confirm": "Potwierdź",
"confirmDelete": "Potwierdź usunięcie", "confirmDelete": "Potwierdź usunięcie",
"create": "Utwórz",
"createApp": "Utwórz aplikację", "createApp": "Utwórz aplikację",
"createSuccess": "Utworzono pomyślnie", "createSuccess": "Utworzono pomyślnie",
"defaultVersion": "Domyślna",
"delete": "Usuń", "delete": "Usuń",
"deleteSuccess": "Usunięto pomyślnie",
"deleteWarning": "Tej operacji nie można cofnąć", "deleteWarning": "Tej operacji nie można cofnąć",
"describeDescription": "Służy do opisu aplikacji, wyświetlany na liście aplikacji",
"description": "Opis",
"downloadLink": "Link do pobrania",
"edit": "Edytuj", "edit": "Edytuj",
"editApp": "Edytuj aplikację", "editApp": "Edytuj aplikację",
"nameDescription": "Nazwa aplikacji, wyświetlana na liście aplikacji",
"platform": "Platforma", "platform": "Platforma",
"startupPicture": "Obraz startowy",
"startupPictureDescription": "Obraz startowy, obsługuje obrazy sieciowe i lokalne. Dla obrazów sieciowych, proszę wprowadzić pełny URL obrazu",
"startupPicturePreview": "Podgląd obrazu startowego",
"startupPictureSkip": "Czas pominięcia obrazu startowego",
"startupPictureSkipDescription": "Czas wyświetlania obrazu startowego w sekundach, wprowadź 0, aby nie wyświetlać",
"subscriptionProtocol": "Protokół subskrypcji", "subscriptionProtocol": "Protokół subskrypcji",
"updateSuccess": "Zaktualizowano pomyślnie" "updateSuccess": "Zaktualizowano pomyślnie",
"version": "Wersja"
}, },
"cancel": "Anuluj", "cancel": "Anuluj",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "ações", "actions": "ações",
"app": { "app": {
"add": "Adicionar",
"appDownloadURL": "URL de Download do App", "appDownloadURL": "URL de Download do App",
"appIcon": "Ícone do App", "appIcon": "Ícone do App",
"appList": "Lista de Apps",
"appName": "Nome do App", "appName": "Nome do App",
"backupDomains": "Lista de Domínios de Backup",
"backupDomainsDescription": "Lista de domínios de backup para resolução de domínios, um domínio por linha",
"batchDelete": "Excluir em Lote", "batchDelete": "Excluir em Lote",
"cancel": "Cancelar", "cancel": "Cancelar",
"config": "Configuração",
"configApp": "Configuração do App",
"confirm": "Confirmar", "confirm": "Confirmar",
"confirmDelete": "Confirmar Exclusão", "confirmDelete": "Confirmar Exclusão",
"create": "Criar",
"createApp": "Criar App", "createApp": "Criar App",
"createSuccess": "Criado com sucesso", "createSuccess": "Criado com sucesso",
"defaultVersion": "Padrão",
"delete": "Excluir", "delete": "Excluir",
"deleteSuccess": "Excluído com sucesso",
"deleteWarning": "Esta ação não pode ser desfeita", "deleteWarning": "Esta ação não pode ser desfeita",
"describeDescription": "Usado para descrever o aplicativo, exibido na lista de apps",
"description": "Descrição",
"downloadLink": "Link para Download",
"edit": "Editar", "edit": "Editar",
"editApp": "Editar App", "editApp": "Editar App",
"nameDescription": "Nome do aplicativo, exibido na lista de apps",
"platform": "Plataforma", "platform": "Plataforma",
"startupPicture": "Imagem de Inicialização",
"startupPictureDescription": "Imagem de inicialização, suporta imagens de rede e locais. Para imagens de rede, por favor insira a URL completa da imagem",
"startupPicturePreview": "Pré-visualização da Imagem de Inicialização",
"startupPictureSkip": "Tempo de Pular Imagem de Inicialização",
"startupPictureSkipDescription": "Tempo de exibição da imagem de inicialização em segundos, insira 0 para não exibir",
"subscriptionProtocol": "Protocolo de Assinatura", "subscriptionProtocol": "Protocolo de Assinatura",
"updateSuccess": "Atualizado com sucesso" "updateSuccess": "Atualizado com sucesso",
"version": "Versão"
}, },
"cancel": "Cancelar", "cancel": "Cancelar",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "acțiuni", "actions": "acțiuni",
"app": { "app": {
"add": "Adaugă",
"appDownloadURL": "URL Descărcare Aplicație", "appDownloadURL": "URL Descărcare Aplicație",
"appIcon": "Iconiță Aplicație", "appIcon": "Iconiță Aplicație",
"appList": "Listă de aplicații",
"appName": "Nume Aplicație", "appName": "Nume Aplicație",
"backupDomains": "Listă de domenii de rezervă",
"backupDomainsDescription": "Listă de domenii de rezervă pentru rezolvarea domeniilor, un domeniu pe linie",
"batchDelete": "Ștergere în Lot", "batchDelete": "Ștergere în Lot",
"cancel": "Anulează", "cancel": "Anulează",
"config": "Configurație",
"configApp": "Configurația aplicației",
"confirm": "Confirmă", "confirm": "Confirmă",
"confirmDelete": "Confirmă Ștergerea", "confirmDelete": "Confirmă Ștergerea",
"create": "Creează",
"createApp": "Creează Aplicație", "createApp": "Creează Aplicație",
"createSuccess": "Creat cu succes", "createSuccess": "Creat cu succes",
"defaultVersion": "Implicit",
"delete": "Șterge", "delete": "Șterge",
"deleteSuccess": "Șters cu succes",
"deleteWarning": "Această acțiune nu poate fi anulată", "deleteWarning": "Această acțiune nu poate fi anulată",
"describeDescription": "Folosit pentru a descrie aplicația, afișat în lista de aplicații",
"description": "Descriere",
"downloadLink": "Link de descărcare",
"edit": "Editează", "edit": "Editează",
"editApp": "Editează Aplicație", "editApp": "Editează Aplicație",
"nameDescription": "Numele aplicației, afișat în lista de aplicații",
"platform": "Platformă", "platform": "Platformă",
"startupPicture": "Imagine de pornire",
"startupPictureDescription": "Imagine de pornire, suportă imagini de rețea și locale. Pentru imagini de rețea, vă rugăm să introduceți URL-ul complet al imaginii",
"startupPicturePreview": "Previzualizare imagine de pornire",
"startupPictureSkip": "Timp de omitere imagine de pornire",
"startupPictureSkipDescription": "Timpul de afișare a imaginii de pornire în secunde, introduceți 0 pentru a nu afișa",
"subscriptionProtocol": "Protocol de Abonament", "subscriptionProtocol": "Protocol de Abonament",
"updateSuccess": "Actualizat cu succes" "updateSuccess": "Actualizat cu succes",
"version": "Versiune"
}, },
"cancel": "Anulează", "cancel": "Anulează",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "действия", "actions": "действия",
"app": { "app": {
"add": "Добавить",
"appDownloadURL": "URL загрузки приложения", "appDownloadURL": "URL загрузки приложения",
"appIcon": "Иконка приложения", "appIcon": "Иконка приложения",
"appList": "Список приложений",
"appName": "Название приложения", "appName": "Название приложения",
"backupDomains": "Список резервных доменов",
"backupDomainsDescription": "Список резервных доменов для разрешения доменов, по одному домену на строку",
"batchDelete": "Удалить пакетно", "batchDelete": "Удалить пакетно",
"cancel": "Отмена", "cancel": "Отмена",
"config": "Конфигурация",
"configApp": "Конфигурация приложения",
"confirm": "Подтвердить", "confirm": "Подтвердить",
"confirmDelete": "Подтвердить удаление", "confirmDelete": "Подтвердить удаление",
"create": "Создать",
"createApp": "Создать приложение", "createApp": "Создать приложение",
"createSuccess": "Успешно создано", "createSuccess": "Успешно создано",
"defaultVersion": "По умолчанию",
"delete": "Удалить", "delete": "Удалить",
"deleteSuccess": "Успешно удалено",
"deleteWarning": "Это действие необратимо", "deleteWarning": "Это действие необратимо",
"describeDescription": "Используется для описания приложения, отображается в списке приложений",
"description": "Описание",
"downloadLink": "Ссылка для загрузки",
"edit": "Редактировать", "edit": "Редактировать",
"editApp": "Редактировать приложение", "editApp": "Редактировать приложение",
"nameDescription": "Название приложения, отображается в списке приложений",
"platform": "Платформа", "platform": "Платформа",
"startupPicture": "Стартовое изображение",
"startupPictureDescription": "Стартовое изображение, поддерживает сетевые и локальные изображения. Для сетевых изображений введите полный URL изображения",
"startupPicturePreview": "Предварительный просмотр стартового изображения",
"startupPictureSkip": "Время пропуска стартового изображения",
"startupPictureSkipDescription": "Время отображения стартового изображения в секундах, введите 0, чтобы не отображать",
"subscriptionProtocol": "Протокол подписки", "subscriptionProtocol": "Протокол подписки",
"updateSuccess": "Успешно обновлено" "updateSuccess": "Успешно обновлено",
"version": "Версия"
}, },
"cancel": "Отмена", "cancel": "Отмена",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "การดำเนินการ", "actions": "การดำเนินการ",
"app": { "app": {
"add": "เพิ่ม",
"appDownloadURL": "URL ดาวน์โหลดแอป", "appDownloadURL": "URL ดาวน์โหลดแอป",
"appIcon": "ไอคอนแอป", "appIcon": "ไอคอนแอป",
"appList": "รายการแอป",
"appName": "ชื่อแอป", "appName": "ชื่อแอป",
"backupDomains": "รายการโดเมนสำรอง",
"backupDomainsDescription": "รายการโดเมนสำรองสำหรับการแก้ไขโดเมน หนึ่งโดเมนต่อบรรทัด",
"batchDelete": "ลบเป็นกลุ่ม", "batchDelete": "ลบเป็นกลุ่ม",
"cancel": "ยกเลิก", "cancel": "ยกเลิก",
"config": "การตั้งค่า",
"configApp": "การตั้งค่าแอป",
"confirm": "ยืนยัน", "confirm": "ยืนยัน",
"confirmDelete": "ยืนยันการลบ", "confirmDelete": "ยืนยันการลบ",
"create": "สร้าง",
"createApp": "สร้างแอป", "createApp": "สร้างแอป",
"createSuccess": "สร้างสำเร็จ", "createSuccess": "สร้างสำเร็จ",
"defaultVersion": "ค่าเริ่มต้น",
"delete": "ลบ", "delete": "ลบ",
"deleteSuccess": "ลบสำเร็จ",
"deleteWarning": "การกระทำนี้ไม่สามารถย้อนกลับได้", "deleteWarning": "การกระทำนี้ไม่สามารถย้อนกลับได้",
"describeDescription": "ใช้เพื่ออธิบายแอปพลิเคชัน แสดงในรายการแอป",
"description": "คำอธิบาย",
"downloadLink": "ลิงก์ดาวน์โหลด",
"edit": "แก้ไข", "edit": "แก้ไข",
"editApp": "แก้ไขแอป", "editApp": "แก้ไขแอป",
"nameDescription": "ชื่อแอปพลิเคชัน แสดงในรายการแอป",
"platform": "แพลตฟอร์ม", "platform": "แพลตฟอร์ม",
"startupPicture": "ภาพเริ่มต้น",
"startupPictureDescription": "ภาพเริ่มต้น รองรับภาพจากเครือข่ายและภาพในเครื่อง สำหรับภาพจากเครือข่าย กรุณาใส่ URL ของภาพให้ครบถ้วน",
"startupPicturePreview": "ดูตัวอย่างภาพเริ่มต้น",
"startupPictureSkip": "เวลาข้ามภาพเริ่มต้น",
"startupPictureSkipDescription": "เวลาแสดงภาพเริ่มต้นเป็นวินาที ใส่ 0 เพื่อไม่แสดง",
"subscriptionProtocol": "โปรโตคอลการสมัครสมาชิก", "subscriptionProtocol": "โปรโตคอลการสมัครสมาชิก",
"updateSuccess": "อัปเดตสำเร็จ" "updateSuccess": "อัปเดตสำเร็จ",
"version": "เวอร์ชัน"
}, },
"cancel": "ยกเลิก", "cancel": "ยกเลิก",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "eylemler", "actions": "eylemler",
"app": { "app": {
"add": "Ekle",
"appDownloadURL": "Uygulama İndirme URL'si", "appDownloadURL": "Uygulama İndirme URL'si",
"appIcon": "Uygulama Simgesi", "appIcon": "Uygulama Simgesi",
"appList": "Uygulama Listesi",
"appName": "Uygulama Adı", "appName": "Uygulama Adı",
"backupDomains": "Yedek Alan Adı Listesi",
"backupDomainsDescription": "Alan adı çözümlemesi için yedek alan adı listesi, her satıra bir alan adı",
"batchDelete": "Toplu Sil", "batchDelete": "Toplu Sil",
"cancel": "İptal", "cancel": "İptal",
"config": "Yapılandırma",
"configApp": "Uygulama Yapılandırması",
"confirm": "Onayla", "confirm": "Onayla",
"confirmDelete": "Silme İşlemini Onayla", "confirmDelete": "Silme İşlemini Onayla",
"create": "Oluştur",
"createApp": "Uygulama Oluştur", "createApp": "Uygulama Oluştur",
"createSuccess": "Başarıyla oluşturuldu", "createSuccess": "Başarıyla oluşturuldu",
"defaultVersion": "Varsayılan",
"delete": "Sil", "delete": "Sil",
"deleteSuccess": "Başarıyla silindi",
"deleteWarning": "Bu işlem geri alınamaz", "deleteWarning": "Bu işlem geri alınamaz",
"describeDescription": "Uygulamayı tanımlamak için kullanılır, uygulama listesinde görüntülenir",
"description": "Açıklama",
"downloadLink": "İndirme Bağlantısı",
"edit": "Düzenle", "edit": "Düzenle",
"editApp": "Uygulamayı Düzenle", "editApp": "Uygulamayı Düzenle",
"nameDescription": "Uygulama adı, uygulama listesinde görüntülenir",
"platform": "Platform", "platform": "Platform",
"startupPicture": "Başlangıç Resmi",
"startupPictureDescription": "Başlangıç resmi, ağ ve yerel resimleri destekler. Ağ resimleri için lütfen tam resim URL'sini girin",
"startupPicturePreview": "Başlangıç Resmi Önizlemesi",
"startupPictureSkip": "Başlangıç Resmi Atla Süresi",
"startupPictureSkipDescription": "Başlangıç resminin görüntülenme süresi saniye cinsinden, görüntülenmemesi için 0 girin",
"subscriptionProtocol": "Abonelik Protokolü", "subscriptionProtocol": "Abonelik Protokolü",
"updateSuccess": "Başarıyla güncellendi" "updateSuccess": "Başarıyla güncellendi",
"version": "Sürüm"
}, },
"cancel": "İptal", "cancel": "İptal",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "дії", "actions": "дії",
"app": { "app": {
"add": "Додати",
"appDownloadURL": "URL завантаження додатку", "appDownloadURL": "URL завантаження додатку",
"appIcon": "Іконка додатку", "appIcon": "Іконка додатку",
"appList": "Список додатків",
"appName": "Назва додатку", "appName": "Назва додатку",
"backupDomains": "Список резервних доменів",
"backupDomainsDescription": "Список резервних доменів для вирішення доменів, один домен на рядок",
"batchDelete": "Пакетне видалення", "batchDelete": "Пакетне видалення",
"cancel": "Скасувати", "cancel": "Скасувати",
"config": "Конфігурація",
"configApp": "Конфігурація додатка",
"confirm": "Підтвердити", "confirm": "Підтвердити",
"confirmDelete": "Підтвердити видалення", "confirmDelete": "Підтвердити видалення",
"create": "Створити",
"createApp": "Створити додаток", "createApp": "Створити додаток",
"createSuccess": "Успішно створено", "createSuccess": "Успішно створено",
"defaultVersion": "За замовчуванням",
"delete": "Видалити", "delete": "Видалити",
"deleteSuccess": "Успішно видалено",
"deleteWarning": "Цю дію не можна скасувати", "deleteWarning": "Цю дію не можна скасувати",
"describeDescription": "Використовується для опису додатка, відображається у списку додатків",
"description": "Опис",
"downloadLink": "Посилання для завантаження",
"edit": "Редагувати", "edit": "Редагувати",
"editApp": "Редагувати додаток", "editApp": "Редагувати додаток",
"nameDescription": "Назва додатка, відображається у списку додатків",
"platform": "Платформа", "platform": "Платформа",
"startupPicture": "Зображення при запуску",
"startupPictureDescription": "Зображення при запуску, підтримуються мережеві та локальні зображення. Для мережевих зображень, будь ласка, введіть повну URL-адресу зображення",
"startupPicturePreview": "Попередній перегляд зображення при запуску",
"startupPictureSkip": "Час пропуску зображення при запуску",
"startupPictureSkipDescription": "Час відображення зображення при запуску в секундах, введіть 0, щоб не відображати",
"subscriptionProtocol": "Протокол підписки", "subscriptionProtocol": "Протокол підписки",
"updateSuccess": "Успішно оновлено" "updateSuccess": "Успішно оновлено",
"version": "Версія"
}, },
"cancel": "Скасувати", "cancel": "Скасувати",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "Hành động", "actions": "Hành động",
"app": { "app": {
"add": "Thêm",
"appDownloadURL": "URL Tải Ứng Dụng", "appDownloadURL": "URL Tải Ứng Dụng",
"appIcon": "Biểu Tượng Ứng Dụng", "appIcon": "Biểu Tượng Ứng Dụng",
"appList": "Danh sách ứng dụng",
"appName": "Tên Ứng Dụng", "appName": "Tên Ứng Dụng",
"backupDomains": "Danh sách miền dự phòng",
"backupDomainsDescription": "Danh sách miền dự phòng cho việc phân giải miền, mỗi dòng một miền",
"batchDelete": "Xóa Hàng Loạt", "batchDelete": "Xóa Hàng Loạt",
"cancel": "Hủy", "cancel": "Hủy",
"config": "Cấu hình",
"configApp": "Cấu hình ứng dụng",
"confirm": "Xác Nhận", "confirm": "Xác Nhận",
"confirmDelete": "Xác Nhận Xóa", "confirmDelete": "Xác Nhận Xóa",
"create": "Tạo mới",
"createApp": "Tạo Ứng Dụng", "createApp": "Tạo Ứng Dụng",
"createSuccess": "Tạo thành công", "createSuccess": "Tạo thành công",
"defaultVersion": "Mặc định",
"delete": "Xóa", "delete": "Xóa",
"deleteSuccess": "Xóa thành công",
"deleteWarning": "Hành động này không thể hoàn tác", "deleteWarning": "Hành động này không thể hoàn tác",
"describeDescription": "Dùng để mô tả ứng dụng, hiển thị trong danh sách ứng dụng",
"description": "Mô tả",
"downloadLink": "Liên kết tải về",
"edit": "Chỉnh Sửa", "edit": "Chỉnh Sửa",
"editApp": "Chỉnh Sửa Ứng Dụng", "editApp": "Chỉnh Sửa Ứng Dụng",
"nameDescription": "Tên ứng dụng, hiển thị trong danh sách ứng dụng",
"platform": "Nền Tảng", "platform": "Nền Tảng",
"startupPicture": "Hình ảnh khởi động",
"startupPictureDescription": "Hình ảnh khởi động, hỗ trợ hình ảnh mạng và cục bộ. Đối với hình ảnh mạng, vui lòng nhập URL hình ảnh đầy đủ",
"startupPicturePreview": "Xem trước hình ảnh khởi động",
"startupPictureSkip": "Thời gian bỏ qua hình ảnh khởi động",
"startupPictureSkipDescription": "Thời gian hiển thị hình ảnh khởi động tính bằng giây, nhập 0 để không hiển thị",
"subscriptionProtocol": "Giao Thức Đăng Ký", "subscriptionProtocol": "Giao Thức Đăng Ký",
"updateSuccess": "Cập nhật thành công" "updateSuccess": "Cập nhật thành công",
"version": "Phiên bản"
}, },
"cancel": "Hủy", "cancel": "Hủy",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "操作", "actions": "操作",
"app": { "app": {
"add": "添加",
"appDownloadURL": "应用下载链接", "appDownloadURL": "应用下载链接",
"appIcon": "应用图标", "appIcon": "应用图标",
"appList": "应用列表",
"appName": "应用名称", "appName": "应用名称",
"backupDomains": "备用域名列表",
"backupDomainsDescription": "用于域名解析的备用域名列表,每行一个域名",
"batchDelete": "批量删除", "batchDelete": "批量删除",
"cancel": "取消", "cancel": "取消",
"config": "配置",
"configApp": "应用配置",
"confirm": "确认", "confirm": "确认",
"confirmDelete": "确认删除", "confirmDelete": "确认删除",
"create": "创建",
"createApp": "创建应用", "createApp": "创建应用",
"createSuccess": "创建成功", "createSuccess": "创建成功",
"defaultVersion": "默认",
"delete": "删除", "delete": "删除",
"deleteSuccess": "删除成功",
"deleteWarning": "此操作无法撤销", "deleteWarning": "此操作无法撤销",
"describeDescription": "用于描述应用程序,显示在应用列表中",
"description": "描述",
"downloadLink": "下载链接",
"edit": "编辑", "edit": "编辑",
"editApp": "编辑应用", "editApp": "编辑应用",
"nameDescription": "应用程序名称,显示在应用列表中",
"platform": "平台", "platform": "平台",
"startupPicture": "启动图片",
"startupPictureDescription": "启动图片支持网络和本地图片。对于网络图片请输入完整的图片URL",
"startupPicturePreview": "启动图片预览",
"startupPictureSkip": "启动图片跳过时间",
"startupPictureSkipDescription": "启动图片显示时间输入0表示不显示",
"subscriptionProtocol": "订阅协议", "subscriptionProtocol": "订阅协议",
"updateSuccess": "更新成功" "updateSuccess": "更新成功",
"version": "版本"
}, },
"cancel": "取消", "cancel": "取消",
"config": { "config": {

View File

@ -1,24 +1,39 @@
{ {
"actions": "操作", "actions": "操作",
"app": { "app": {
"add": "新增",
"appDownloadURL": "應用程式下載網址", "appDownloadURL": "應用程式下載網址",
"appIcon": "應用程式圖示", "appIcon": "應用程式圖示",
"appList": "應用程式列表",
"appName": "應用程式名稱", "appName": "應用程式名稱",
"backupDomains": "備用域名列表",
"backupDomainsDescription": "用於域名解析的備用域名列表,每行一個域名",
"batchDelete": "批量刪除", "batchDelete": "批量刪除",
"cancel": "取消", "cancel": "取消",
"config": "配置",
"configApp": "應用程式配置",
"confirm": "確認", "confirm": "確認",
"confirmDelete": "確認刪除", "confirmDelete": "確認刪除",
"create": "創建",
"createApp": "創建應用程式", "createApp": "創建應用程式",
"createSuccess": "創建成功", "createSuccess": "創建成功",
"defaultVersion": "默認",
"delete": "刪除", "delete": "刪除",
"deleteSuccess": "刪除成功",
"deleteWarning": "此操作無法撤銷", "deleteWarning": "此操作無法撤銷",
"describeDescription": "用於描述應用程式,顯示在應用程式列表中",
"description": "描述",
"downloadLink": "下載連結",
"edit": "編輯", "edit": "編輯",
"editApp": "編輯應用程式", "editApp": "編輯應用程式",
"nameDescription": "應用程式名稱,顯示在應用程式列表中",
"platform": "平台", "platform": "平台",
"startupPicture": "啟動圖片",
"startupPictureDescription": "啟動圖片支持網絡和本地圖片。對於網絡圖片請輸入完整的圖片URL",
"startupPicturePreview": "啟動圖片預覽",
"startupPictureSkip": "啟動圖片跳過時間",
"startupPictureSkipDescription": "啟動圖片顯示時間輸入0表示不顯示",
"subscriptionProtocol": "訂閱協議", "subscriptionProtocol": "訂閱協議",
"updateSuccess": "更新成功" "updateSuccess": "更新成功",
"version": "版本"
}, },
"cancel": "取消", "cancel": "取消",
"config": { "config": {

View File

@ -10,7 +10,6 @@
"start": "next start" "start": "next start"
}, },
"dependencies": { "dependencies": {
"@iconify/react": "^5.2.0",
"@lottiefiles/dotlottie-react": "^0.12.1", "@lottiefiles/dotlottie-react": "^0.12.1",
"@tanstack/react-query": "^5.63.0", "@tanstack/react-query": "^5.63.0",
"@tanstack/react-query-next-experimental": "^5.63.0", "@tanstack/react-query-next-experimental": "^5.63.0",

View File

@ -0,0 +1,101 @@
// @ts-ignore
/* eslint-disable */
import request from '@/utils/request';
/** get app config GET /v1/admin/app/config */
export async function getAppConfig(options?: { [key: string]: any }) {
return request<API.Response & { data?: API.AppConfig }>('/v1/admin/app/config', {
method: 'GET',
...(options || {}),
});
}
/** update app config PUT /v1/admin/app/config */
export async function updateAppConfig(body: API.AppConfig, options?: { [key: string]: any }) {
return request<API.Response & { data?: any }>('/v1/admin/app/config', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** update app version PUT /v1/admin/app/version */
export async function updateAppVersion(
body: API.UpdateAppVersionRequest,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: any }>('/v1/admin/app/version', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** create app version POST /v1/admin/app/version */
export async function createAppVersion(
body: API.CreateAppVersionRequest,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: any }>('/v1/admin/app/version', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** delete app version DELETE /v1/admin/app/version */
export async function deleteAppVersionInfo(
body: API.DeleteAppVersionRequest,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: any }>('/v1/admin/app/version', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** set default app version PUT /v1/admin/app/version_default */
export async function setDefaultAppVersionInfo(
body: API.DefaultAppVersionRequest,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: any }>('/v1/admin/app/version_default', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** query app version info GET /v1/admin/app/version_list */
export async function getAppVersionList(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.GetAppVersionListParams,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: API.GetAppVersionListResponse }>(
'/v1/admin/app/version_list',
{
method: 'GET',
params: {
...params,
},
...(options || {}),
},
);
}

View File

@ -3,6 +3,7 @@
// API 更新时间: // API 更新时间:
// API 唯一标识: // API 唯一标识:
import * as announcement from './announcement'; import * as announcement from './announcement';
import * as app from './app';
import * as console from './console'; import * as console from './console';
import * as coupon from './coupon'; import * as coupon from './coupon';
import * as document from './document'; import * as document from './document';
@ -17,6 +18,7 @@ import * as tool from './tool';
import * as user from './user'; import * as user from './user';
export default { export default {
announcement, announcement,
app,
console, console,
coupon, coupon,
document, document,

View File

@ -58,6 +58,51 @@ export async function deleteApplication(
}); });
} }
/** Update application version PUT /v1/admin/system/application_version */
export async function updateApplicationVersion(
body: API.UpdateApplicationVersionRequest,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: any }>('/v1/admin/system/application_version', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** Create application version POST /v1/admin/system/application_version */
export async function createApplicationVersion(
body: API.CreateApplicationVersionRequest,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: any }>('/v1/admin/system/application_version', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** Delete application DELETE /v1/admin/system/application_version */
export async function deleteApplicationVersion(
body: API.DeleteApplicationVersionRequest,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: any }>('/v1/admin/system/application_version', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** Get Currency Config GET /v1/admin/system/currency_config */ /** Get Currency Config GET /v1/admin/system/currency_config */
export async function getCurrencyConfig(options?: { [key: string]: any }) { export async function getCurrencyConfig(options?: { [key: string]: any }) {
return request<API.Response & { data?: API.CurrencyConfig }>('/v1/admin/system/currency_config', { return request<API.Response & { data?: API.CurrencyConfig }>('/v1/admin/system/currency_config', {

View File

@ -18,21 +18,59 @@ declare namespace API {
updated_at: number; updated_at: number;
}; };
type AppConfig = {
name: string;
domains: string[];
describe: string;
startup_picture: string;
startup_picture_skip_time: number;
};
type Application = { type Application = {
id: number; id: number;
name: string;
platform: string;
subscribe_type: string;
icon: string; icon: string;
url: string; name: string;
description: string;
subscribe_type: string;
};
type ApplicationPlatform = {
ios?: ApplicationVersion[];
mac?: ApplicationVersion[];
linux?: ApplicationVersion[];
android?: ApplicationVersion[];
windows?: ApplicationVersion[];
harmony?: ApplicationVersion[];
}; };
type ApplicationResponse = { type ApplicationResponse = {
windows: Application[]; applications: ApplicationResponseInfo[];
mac: Application[]; };
linux: Application[];
android: Application[]; type ApplicationResponseInfo = {
ios: Application[]; id: number;
name: string;
icon: string;
description: string;
subscription_protocol: string;
platform: ApplicationPlatform;
};
type ApplicationVersion = {
id: number;
url: string;
version: string;
description: string;
is_default: boolean;
};
type AppVersion = {
id: number;
os: string;
version: string;
download_url: string;
describe: string;
default_version: boolean;
}; };
type AuthConfig = { type AuthConfig = {
@ -92,11 +130,26 @@ declare namespace API {
}; };
type CreateApplicationRequest = { type CreateApplicationRequest = {
name: string;
platform: 'windows' | 'mac' | 'linux' | 'android' | 'ios';
subscribe_type: string;
icon: string; icon: string;
name: string;
description: string;
subscribe_type: string;
};
type CreateApplicationVersionRequest = {
url: string; url: string;
version: string;
description: string;
platform: 'windows' | 'mac' | 'linux' | 'android' | 'ios' | 'harmony';
is_default: boolean;
application_id: number;
};
type CreateAppVersionRequest = {
os: string;
version: string;
download_url: string;
describe: string;
}; };
type CreateCouponRequest = { type CreateCouponRequest = {
@ -214,6 +267,10 @@ declare namespace API {
currency_symbol: string; currency_symbol: string;
}; };
type DefaultAppVersionRequest = {
id: number;
};
type DeleteAnnouncementRequest = { type DeleteAnnouncementRequest = {
id: number; id: number;
}; };
@ -222,6 +279,14 @@ declare namespace API {
id: number; id: number;
}; };
type DeleteApplicationVersionRequest = {
id: number;
};
type DeleteAppVersionRequest = {
id: number;
};
type DeleteCouponRequest = { type DeleteCouponRequest = {
id: number; id: number;
}; };
@ -333,6 +398,23 @@ declare namespace API {
id: number; id: number;
}; };
type GetAppVersionListParams = {
page: number;
size: number;
os?: string;
};
type GetAppVersionListRequest = {
page: number;
size: number;
os?: string;
};
type GetAppVersionListResponse = {
total: number;
list: AppVersion[];
};
type GetCouponListParams = { type GetCouponListParams = {
page: number; page: number;
size: number; size: number;
@ -984,10 +1066,28 @@ declare namespace API {
type UpdateApplicationRequest = { type UpdateApplicationRequest = {
id: number; id: number;
name: string;
subscribe_type: string;
icon: string; icon: string;
name: string;
description: string;
subscribe_type: string;
};
type UpdateApplicationVersionRequest = {
id: number;
url: string; url: string;
version: string;
description: string;
platform: 'windows' | 'mac' | 'linux' | 'android' | 'ios' | 'harmony';
is_default: boolean;
application_id: number;
};
type UpdateAppVersionRequest = {
id: number;
os: string;
version: string;
download_url: string;
describe: string;
}; };
type UpdateCouponRequest = { type UpdateCouponRequest = {

View File

@ -2,6 +2,14 @@
/* eslint-disable */ /* eslint-disable */
import request from '@/utils/request'; import request from '@/utils/request';
/** Get Tos Content GET /v1/common/app/info */
export async function getAppInfo(options?: { [key: string]: any }) {
return request<API.Response & { data?: API.GetAppInfoResponse }>('/v1/common/app/info', {
method: 'GET',
...(options || {}),
});
}
/** Get verification code POST /v1/common/send_code */ /** Get verification code POST /v1/common/send_code */
export async function sendEmailCode(body: API.SendCodeRequest, options?: { [key: string]: any }) { export async function sendEmailCode(body: API.SendCodeRequest, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.SendCodeResponse }>('/v1/common/send_code', { return request<API.Response & { data?: API.SendCodeResponse }>('/v1/common/send_code', {

View File

@ -10,21 +10,59 @@ declare namespace API {
updated_at: number; updated_at: number;
}; };
type AppConfig = {
name: string;
domains: string[];
describe: string;
startup_picture: string;
startup_picture_skip_time: number;
};
type Application = { type Application = {
id: number; id: number;
name: string;
platform: string;
subscribe_type: string;
icon: string; icon: string;
url: string; name: string;
description: string;
subscribe_type: string;
};
type ApplicationPlatform = {
ios?: ApplicationVersion[];
mac?: ApplicationVersion[];
linux?: ApplicationVersion[];
android?: ApplicationVersion[];
windows?: ApplicationVersion[];
harmony?: ApplicationVersion[];
}; };
type ApplicationResponse = { type ApplicationResponse = {
windows: Application[]; applications: ApplicationResponseInfo[];
mac: Application[]; };
linux: Application[];
android: Application[]; type ApplicationResponseInfo = {
ios: Application[]; id: number;
name: string;
icon: string;
description: string;
subscription_protocol: string;
platform: ApplicationPlatform;
};
type ApplicationVersion = {
id: number;
url: string;
version: string;
description: string;
is_default: boolean;
};
type AppVersion = {
id: number;
os: string;
version: string;
download_url: string;
describe: string;
default_version: boolean;
}; };
type AuthConfig = { type AuthConfig = {
@ -113,6 +151,11 @@ declare namespace API {
created_at: number; created_at: number;
}; };
type GetAppInfoResponse = {
config: AppConfig;
versions: AppVersion[];
};
type GetGlobalConfigResponse = { type GetGlobalConfigResponse = {
site: SiteConfig; site: SiteConfig;
verify: VeifyConfig; verify: VeifyConfig;

View File

@ -9,7 +9,6 @@ import { getStat } from '@/services/common/common';
import { queryApplicationConfig } from '@/services/user/subscribe'; import { queryApplicationConfig } from '@/services/user/subscribe';
import { queryUserSubscribe } from '@/services/user/user'; import { queryUserSubscribe } from '@/services/user/user';
import { getPlatform } from '@/utils/common'; import { getPlatform } from '@/utils/common';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { import {
Accordion, Accordion,
@ -32,6 +31,7 @@ import { Button } from '@workspace/ui/components/button';
import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card'; import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card';
import { Separator } from '@workspace/ui/components/separator'; import { Separator } from '@workspace/ui/components/separator';
import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs'; import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
import { Icon } from '@workspace/ui/custom-components/icon';
import { isBrowser } from '@workspace/ui/utils'; import { isBrowser } from '@workspace/ui/utils';
import { differenceInDays } from 'date-fns'; import { differenceInDays } from 'date-fns';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';

View File

@ -5,7 +5,6 @@ import { SubscribeBilling } from '@/components/subscribe/billing';
import { SubscribeDetail } from '@/components/subscribe/detail'; import { SubscribeDetail } from '@/components/subscribe/detail';
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { checkoutOrder, queryOrderDetail } from '@/services/user/order'; import { checkoutOrder, queryOrderDetail } from '@/services/user/order';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { Badge } from '@workspace/ui/components/badge'; import { Badge } from '@workspace/ui/components/badge';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
@ -17,6 +16,7 @@ import {
CardTitle, CardTitle,
} from '@workspace/ui/components/card'; } from '@workspace/ui/components/card';
import { Separator } from '@workspace/ui/components/separator'; import { Separator } from '@workspace/ui/components/separator';
import { Icon } from '@workspace/ui/custom-components/icon';
import { formatDate } from '@workspace/ui/utils'; import { formatDate } from '@workspace/ui/utils';
import { useCountDown } from 'ahooks'; import { useCountDown } from 'ahooks';
import { addMinutes, format } from 'date-fns'; import { addMinutes, format } from 'date-fns';

View File

@ -1,6 +1,5 @@
'use client'; 'use client';
import { navs } from '@/config/navs'; import { navs } from '@/config/navs';
import { Icon } from '@iconify/react';
import { import {
Sidebar, Sidebar,
SidebarContent, SidebarContent,
@ -11,6 +10,7 @@ import {
SidebarMenuButton, SidebarMenuButton,
SidebarMenuItem, SidebarMenuItem,
} from '@workspace/ui/components/sidebar'; } from '@workspace/ui/components/sidebar';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import Link from 'next/link'; import Link from 'next/link';
import { usePathname } from 'next/navigation'; import { usePathname } from 'next/navigation';

View File

@ -3,7 +3,6 @@
import { Display } from '@/components/display'; import { Display } from '@/components/display';
import Recharge from '@/components/subscribe/recharge'; import Recharge from '@/components/subscribe/recharge';
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { Icon } from '@iconify/react';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card'; import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card';
import { Sidebar, SidebarContent } from '@workspace/ui/components/sidebar'; import { Sidebar, SidebarContent } from '@workspace/ui/components/sidebar';
@ -13,6 +12,7 @@ import {
TooltipProvider, TooltipProvider,
TooltipTrigger, TooltipTrigger,
} from '@workspace/ui/components/tooltip'; } from '@workspace/ui/components/tooltip';
import { Icon } from '@workspace/ui/custom-components/icon';
import { isBrowser } from '@workspace/ui/utils'; import { isBrowser } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import CopyToClipboard from 'react-copy-to-clipboard'; import CopyToClipboard from 'react-copy-to-clipboard';

View File

@ -2,12 +2,12 @@
import { Display } from '@/components/display'; import { Display } from '@/components/display';
import { querySubscribeGroupList, querySubscribeList } from '@/services/user/subscribe'; import { querySubscribeGroupList, querySubscribeList } from '@/services/user/subscribe';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Card, CardContent, CardFooter, CardHeader } from '@workspace/ui/components/card'; import { Card, CardContent, CardFooter, CardHeader } from '@workspace/ui/components/card';
import { Separator } from '@workspace/ui/components/separator'; import { Separator } from '@workspace/ui/components/separator';
import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs'; import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
import { Icon } from '@workspace/ui/custom-components/icon';
import { cn } from '@workspace/ui/lib/utils'; import { cn } from '@workspace/ui/lib/utils';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { useState } from 'react'; import { useState } from 'react';

View File

@ -9,7 +9,6 @@ import {
getUserTicketList, getUserTicketList,
updateUserTicketStatus, updateUserTicketStatus,
} from '@/services/user/ticket'; } from '@/services/user/ticket';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { import {
@ -41,6 +40,7 @@ import { Label } from '@workspace/ui/components/label';
import { ScrollArea } from '@workspace/ui/components/scroll-area'; import { ScrollArea } from '@workspace/ui/components/scroll-area';
import { Textarea } from '@workspace/ui/components/textarea'; import { Textarea } from '@workspace/ui/components/textarea';
import { ConfirmButton } from '@workspace/ui/custom-components/confirm-button'; import { ConfirmButton } from '@workspace/ui/custom-components/confirm-button';
import { Icon } from '@workspace/ui/custom-components/icon';
import { cn } from '@workspace/ui/lib/utils'; import { cn } from '@workspace/ui/lib/utils';
import { formatDate } from '@workspace/ui/utils'; import { formatDate } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';

View File

@ -1,9 +1,9 @@
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form';
import { Input } from '@workspace/ui/components/input'; import { Input } from '@workspace/ui/components/input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { Dispatch, SetStateAction } from 'react'; import { Dispatch, SetStateAction } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
@ -60,12 +60,7 @@ export default function LoginForm({
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormControl> <FormControl>
<Input <Input placeholder='Enter your password...' type='password' {...field} />
disabled={loading}
placeholder='Enter your password...'
type='password'
{...field}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>

View File

@ -1,9 +1,9 @@
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form';
import { Input } from '@workspace/ui/components/input'; import { Input } from '@workspace/ui/components/input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { Markdown } from '@workspace/ui/custom-components/markdown'; import { Markdown } from '@workspace/ui/custom-components/markdown';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { Dispatch, SetStateAction } from 'react'; import { Dispatch, SetStateAction } from 'react';
@ -102,12 +102,7 @@ export default function RegisterForm({
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormControl> <FormControl>
<Input <Input placeholder='Enter your password...' type='password' {...field} />
disabled={loading}
placeholder='Enter your password...'
type='password'
{...field}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>

View File

@ -1,9 +1,9 @@
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form';
import { Input } from '@workspace/ui/components/input'; import { Input } from '@workspace/ui/components/input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { Dispatch, SetStateAction } from 'react'; import { Dispatch, SetStateAction } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
@ -65,12 +65,7 @@ export default function ResetForm({
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormControl> <FormControl>
<Input <Input placeholder='Enter your password...' type='password' {...field} />
disabled={loading}
placeholder='Enter your password...'
type='password'
{...field}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>

View File

@ -1,10 +1,10 @@
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form';
import { Input } from '@workspace/ui/components/input'; import { Input } from '@workspace/ui/components/input';
import { AreaCodeSelect } from '@workspace/ui/custom-components/area-code-select'; import { AreaCodeSelect } from '@workspace/ui/custom-components/area-code-select';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { Dispatch, SetStateAction, useState } from 'react'; import { Dispatch, SetStateAction, useState } from 'react';
@ -99,7 +99,6 @@ export default function LoginForm({
<FormControl> <FormControl>
<div className='flex gap-2'> <div className='flex gap-2'>
<Input <Input
disabled={loading}
placeholder={mode === 'code' ? 'Enter code...' : 'Enter password...'} placeholder={mode === 'code' ? 'Enter code...' : 'Enter password...'}
type={mode === 'code' ? 'text' : 'password'} type={mode === 'code' ? 'text' : 'password'}
{...field} {...field}

View File

@ -1,10 +1,10 @@
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form';
import { Input } from '@workspace/ui/components/input'; import { Input } from '@workspace/ui/components/input';
import { AreaCodeSelect } from '@workspace/ui/custom-components/area-code-select'; import { AreaCodeSelect } from '@workspace/ui/custom-components/area-code-select';
import { Icon } from '@workspace/ui/custom-components/icon';
import { Markdown } from '@workspace/ui/custom-components/markdown'; import { Markdown } from '@workspace/ui/custom-components/markdown';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { Dispatch, SetStateAction } from 'react'; import { Dispatch, SetStateAction } from 'react';
@ -116,12 +116,7 @@ export default function RegisterForm({
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormControl> <FormControl>
<Input <Input placeholder='Enter your password...' type='password' {...field} />
disabled={loading}
placeholder='Enter your password...'
type='password'
{...field}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>

View File

@ -1,10 +1,10 @@
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@workspace/ui/components/form';
import { Input } from '@workspace/ui/components/input'; import { Input } from '@workspace/ui/components/input';
import { AreaCodeSelect } from '@workspace/ui/custom-components/area-code-select'; import { AreaCodeSelect } from '@workspace/ui/custom-components/area-code-select';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { Dispatch, SetStateAction, useState } from 'react'; import { Dispatch, SetStateAction, useState } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
@ -97,12 +97,7 @@ export default function ResetForm({
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormControl> <FormControl>
<Input <Input placeholder='Enter your password...' type='password' {...field} />
disabled={loading}
placeholder='Enter your password...'
type='password'
{...field}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -118,7 +113,6 @@ export default function ResetForm({
<FormControl> <FormControl>
<div className='flex items-center gap-2'> <div className='flex items-center gap-2'>
<Input <Input
disabled={loading}
placeholder='Enter code...' placeholder='Enter code...'
type='text' type='text'
{...field} {...field}

View File

@ -1,7 +1,7 @@
import { queryAnnouncement } from '@/services/user/announcement'; import { queryAnnouncement } from '@/services/user/announcement';
import { Icon } from '@iconify/react';
import { Card } from '@workspace/ui/components/card'; import { Card } from '@workspace/ui/components/card';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@workspace/ui/components/dialog'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@workspace/ui/components/dialog';
import { Icon } from '@workspace/ui/custom-components/icon';
import { Markdown } from '@workspace/ui/custom-components/markdown'; import { Markdown } from '@workspace/ui/custom-components/markdown';
import { getTranslations } from 'next-intl/server'; import { getTranslations } from 'next-intl/server';
import { Empty } from '../empty'; import { Empty } from '../empty';

View File

@ -10,8 +10,8 @@ import {
NEXT_PUBLIC_TWITTER_LINK, NEXT_PUBLIC_TWITTER_LINK,
} from '@/config/constants'; } from '@/config/constants';
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Separator } from '@workspace/ui/components/separator'; import { Separator } from '@workspace/ui/components/separator';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import Link from 'next/link'; import Link from 'next/link';
import { Fragment } from 'react'; import { Fragment } from 'react';

View File

@ -2,7 +2,6 @@
import { locales } from '@/config/constants'; import { locales } from '@/config/constants';
import { setLocale } from '@/utils/common'; import { setLocale } from '@/utils/common';
import { Icon } from '@iconify/react';
import { import {
Select, Select,
SelectContent, SelectContent,
@ -10,6 +9,7 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from '@workspace/ui/components/select'; } from '@workspace/ui/components/select';
import { Icon } from '@workspace/ui/custom-components/icon';
import { getCountry } from '@workspace/ui/utils'; import { getCountry } from '@workspace/ui/utils';
import { useLocale, useTranslations } from 'next-intl'; import { useLocale, useTranslations } from 'next-intl';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';

View File

@ -3,11 +3,11 @@
import { Display } from '@/components/display'; import { Display } from '@/components/display';
import { SubscribeDetail } from '@/components/subscribe/detail'; import { SubscribeDetail } from '@/components/subscribe/detail';
import { getSubscription } from '@/services/common/common'; import { getSubscription } from '@/services/common/common';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Card, CardContent, CardFooter, CardHeader } from '@workspace/ui/components/card'; import { Card, CardContent, CardFooter, CardHeader } from '@workspace/ui/components/card';
import { Separator } from '@workspace/ui/components/separator'; import { Separator } from '@workspace/ui/components/separator';
import { Icon } from '@workspace/ui/custom-components/icon';
import { cn } from '@workspace/ui/lib/utils'; import { cn } from '@workspace/ui/lib/utils';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';

View File

@ -3,7 +3,6 @@
import { navs } from '@/config/navs'; import { navs } from '@/config/navs';
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { Logout } from '@/utils/common'; import { Logout } from '@/utils/common';
import { Icon } from '@iconify/react';
import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/avatar'; import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/avatar';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { import {
@ -15,6 +14,7 @@ import {
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from '@workspace/ui/components/dropdown-menu'; } from '@workspace/ui/components/dropdown-menu';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';

View File

@ -10,7 +10,6 @@
"start": "next start" "start": "next start"
}, },
"dependencies": { "dependencies": {
"@iconify/react": "^5.2.0",
"@stripe/react-stripe-js": "^3.1.1", "@stripe/react-stripe-js": "^3.1.1",
"@stripe/stripe-js": "^5.5.0", "@stripe/stripe-js": "^5.5.0",
"@tanstack/react-query": "^5.63.0", "@tanstack/react-query": "^5.63.0",

View File

@ -2,6 +2,14 @@
/* eslint-disable */ /* eslint-disable */
import request from '@/utils/request'; import request from '@/utils/request';
/** Get Tos Content GET /v1/common/app/info */
export async function getAppInfo(options?: { [key: string]: any }) {
return request<API.Response & { data?: API.GetAppInfoResponse }>('/v1/common/app/info', {
method: 'GET',
...(options || {}),
});
}
/** Get verification code POST /v1/common/send_code */ /** Get verification code POST /v1/common/send_code */
export async function sendEmailCode(body: API.SendCodeRequest, options?: { [key: string]: any }) { export async function sendEmailCode(body: API.SendCodeRequest, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.SendCodeResponse }>('/v1/common/send_code', { return request<API.Response & { data?: API.SendCodeResponse }>('/v1/common/send_code', {

View File

@ -10,21 +10,59 @@ declare namespace API {
updated_at: number; updated_at: number;
}; };
type AppConfig = {
name: string;
domains: string[];
describe: string;
startup_picture: string;
startup_picture_skip_time: number;
};
type Application = { type Application = {
id: number; id: number;
name: string;
platform: string;
subscribe_type: string;
icon: string; icon: string;
url: string; name: string;
description: string;
subscribe_type: string;
};
type ApplicationPlatform = {
ios?: ApplicationVersion[];
mac?: ApplicationVersion[];
linux?: ApplicationVersion[];
android?: ApplicationVersion[];
windows?: ApplicationVersion[];
harmony?: ApplicationVersion[];
}; };
type ApplicationResponse = { type ApplicationResponse = {
windows: Application[]; applications: ApplicationResponseInfo[];
mac: Application[]; };
linux: Application[];
android: Application[]; type ApplicationResponseInfo = {
ios: Application[]; id: number;
name: string;
icon: string;
description: string;
subscription_protocol: string;
platform: ApplicationPlatform;
};
type ApplicationVersion = {
id: number;
url: string;
version: string;
description: string;
is_default: boolean;
};
type AppVersion = {
id: number;
os: string;
version: string;
download_url: string;
describe: string;
default_version: boolean;
}; };
type AuthConfig = { type AuthConfig = {
@ -113,6 +151,11 @@ declare namespace API {
created_at: number; created_at: number;
}; };
type GetAppInfoResponse = {
config: AppConfig;
versions: AppVersion[];
};
type GetGlobalConfigResponse = { type GetGlobalConfigResponse = {
site: SiteConfig; site: SiteConfig;
verify: VeifyConfig; verify: VeifyConfig;

View File

@ -10,21 +10,59 @@ declare namespace API {
updated_at: number; updated_at: number;
}; };
type AppConfig = {
name: string;
domains: string[];
describe: string;
startup_picture: string;
startup_picture_skip_time: number;
};
type Application = { type Application = {
id: number; id: number;
name: string;
platform: string;
subscribe_type: string;
icon: string; icon: string;
url: string; name: string;
description: string;
subscribe_type: string;
};
type ApplicationPlatform = {
ios?: ApplicationVersion[];
mac?: ApplicationVersion[];
linux?: ApplicationVersion[];
android?: ApplicationVersion[];
windows?: ApplicationVersion[];
harmony?: ApplicationVersion[];
}; };
type ApplicationResponse = { type ApplicationResponse = {
windows: Application[]; applications: ApplicationResponseInfo[];
mac: Application[]; };
linux: Application[];
android: Application[]; type ApplicationResponseInfo = {
ios: Application[]; id: number;
name: string;
icon: string;
description: string;
subscription_protocol: string;
platform: ApplicationPlatform;
};
type ApplicationVersion = {
id: number;
url: string;
version: string;
description: string;
is_default: boolean;
};
type AppVersion = {
id: number;
os: string;
version: string;
download_url: string;
describe: string;
default_version: boolean;
}; };
type AuthConfig = { type AuthConfig = {

BIN
bun.lockb

Binary file not shown.

View File

@ -21,6 +21,10 @@
"@dnd-kit/core": "^6.3.1", "@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0", "@dnd-kit/sortable": "^10.0.0",
"@hookform/resolvers": "^3.10.0", "@hookform/resolvers": "^3.10.0",
"@iconify-json/flagpack": "^1.2.2",
"@iconify-json/mdi": "^1.2.2",
"@iconify-json/uil": "^1.2.3",
"@iconify/react": "^5.2.0",
"@monaco-editor/react": "^4.6.0", "@monaco-editor/react": "^4.6.0",
"@radix-ui/react-accordion": "^1.2.2", "@radix-ui/react-accordion": "^1.2.2",
"@radix-ui/react-alert-dialog": "^1.1.4", "@radix-ui/react-alert-dialog": "^1.1.4",

View File

@ -1,6 +1,5 @@
'use client'; 'use client';
import { Icon } from '@iconify/react';
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { import {
Command, Command,
@ -11,6 +10,7 @@ import {
CommandList, CommandList,
} from '@workspace/ui/components/command'; } from '@workspace/ui/components/command';
import { Popover, PopoverContent, PopoverTrigger } from '@workspace/ui/components/popover'; import { Popover, PopoverContent, PopoverTrigger } from '@workspace/ui/components/popover';
import { Icon } from '@workspace/ui/custom-components/icon';
import { cn } from '@workspace/ui/lib/utils'; import { cn } from '@workspace/ui/lib/utils';
import { countries, type ICountry } from '@workspace/ui/utils/countries'; import { countries, type ICountry } from '@workspace/ui/utils/countries';
import { BoxIcon, Check, ChevronsUpDown } from 'lucide-react'; import { BoxIcon, Check, ChevronsUpDown } from 'lucide-react';

View File

@ -1,4 +1,6 @@
import { Button } from '@workspace/ui/components/button'; import { Button } from '@workspace/ui/components/button';
import { Label } from '@workspace/ui/components/label.js';
import { Switch } from '@workspace/ui/components/switch';
import { Combobox } from '@workspace/ui/custom-components/combobox'; import { Combobox } from '@workspace/ui/custom-components/combobox';
import { EnhancedInput, EnhancedInputProps } from '@workspace/ui/custom-components/enhanced-input'; import { EnhancedInput, EnhancedInputProps } from '@workspace/ui/custom-components/enhanced-input';
import { cn } from '@workspace/ui/lib/utils'; import { cn } from '@workspace/ui/lib/utils';
@ -7,7 +9,7 @@ import { useEffect, useState } from 'react';
interface FieldConfig extends Omit<EnhancedInputProps, 'type'> { interface FieldConfig extends Omit<EnhancedInputProps, 'type'> {
name: string; name: string;
type: 'text' | 'number' | 'select' | 'time'; type: 'text' | 'number' | 'select' | 'time' | 'boolean';
options?: { label: string; value: string }[]; options?: { label: string; value: string }[];
internal?: boolean; internal?: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -18,6 +20,7 @@ interface ObjectInputProps<T> {
value: T; value: T;
onChange: (value: T) => void; onChange: (value: T) => void;
fields: FieldConfig[]; fields: FieldConfig[];
className?: string;
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -25,6 +28,7 @@ export function ObjectInput<T extends Record<string, any>>({
value, value,
onChange, onChange,
fields, fields,
className,
}: ObjectInputProps<T>) { }: ObjectInputProps<T>) {
const [internalState, setInternalState] = useState<T>(value); const [internalState, setInternalState] = useState<T>(value);
@ -32,7 +36,7 @@ export function ObjectInput<T extends Record<string, any>>({
setInternalState(value); setInternalState(value);
}, [value]); }, [value]);
const updateField = (key: keyof T, fieldValue: string | number) => { const updateField = (key: keyof T, fieldValue: string | number | boolean) => {
let updatedInternalState = { ...internalState, [key]: fieldValue }; let updatedInternalState = { ...internalState, [key]: fieldValue };
fields.forEach((field) => { fields.forEach((field) => {
if (field.calculateValue && field.name === key) { if (field.calculateValue && field.name === key) {
@ -52,28 +56,44 @@ export function ObjectInput<T extends Record<string, any>>({
onChange(filteredValue); onChange(filteredValue);
}; };
const renderField = (field: FieldConfig) => {
return ( switch (field.type) {
<div className='flex flex-1 flex-wrap gap-4'> case 'select':
{fields.map(({ name, type, options, className, ...fieldProps }) => ( return (
<div key={name} className={cn('flex-1', className)}> field.options && (
{type === 'select' && options ? (
<Combobox<string, false> <Combobox<string, false>
placeholder={fieldProps.placeholder} placeholder={field.placeholder}
options={options} options={field.options}
value={internalState[name]} value={internalState[field.name]}
onChange={(fieldValue) => { onChange={(fieldValue) => updateField(field.name, fieldValue)}
updateField(name, fieldValue);
}}
/> />
) : ( )
<EnhancedInput );
value={internalState[name]} case 'boolean':
onValueChange={(fieldValue) => updateField(name, fieldValue)} return (
type={type} <div className='flex h-full items-center space-x-2'>
{...fieldProps} <Switch
checked={internalState[field.name] as boolean}
onCheckedChange={(fieldValue) => updateField(field.name, fieldValue)}
/> />
)} {field.placeholder && <Label>{field.placeholder}</Label>}
</div>
);
default:
return (
<EnhancedInput
value={internalState[field.name]}
onValueChange={(fieldValue) => updateField(field.name, fieldValue)}
{...field}
/>
);
}
};
return (
<div className={cn('flex flex-1 flex-wrap gap-4', className)}>
{fields.map((field) => (
<div key={field.name} className={cn('flex-1', field.className)}>
{renderField(field)}
</div> </div>
))} ))}
</div> </div>
@ -83,6 +103,8 @@ interface ArrayInputProps<T> {
value?: T[]; value?: T[];
onChange: (value: T[]) => void; onChange: (value: T[]) => void;
fields: FieldConfig[]; fields: FieldConfig[];
isReverse?: boolean;
className?: string;
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -90,6 +112,8 @@ export function ArrayInput<T extends Record<string, any>>({
value = [], value = [],
onChange, onChange,
fields, fields,
isReverse = false,
className,
}: ArrayInputProps<T>) { }: ArrayInputProps<T>) {
const initializeDefaultItem = (): T => const initializeDefaultItem = (): T =>
fields.reduce((acc, field) => { fields.reduce((acc, field) => {
@ -117,7 +141,11 @@ export function ArrayInput<T extends Record<string, any>>({
}; };
const createField = () => { const createField = () => {
setDisplayItems([...displayItems, initializeDefaultItem()]); if (isReverse) {
setDisplayItems([initializeDefaultItem(), ...displayItems]);
} else {
setDisplayItems([...displayItems, initializeDefaultItem()]);
}
}; };
const deleteField = (index: number) => { const deleteField = (index: number) => {
@ -142,6 +170,7 @@ export function ArrayInput<T extends Record<string, any>>({
value={item} value={item}
onChange={(updatedItem) => handleItemChange(index, updatedItem)} onChange={(updatedItem) => handleItemChange(index, updatedItem)}
fields={fields} fields={fields}
className={className}
/> />
<div className='flex min-w-20 items-center'> <div className='flex min-w-20 items-center'>
{displayItems.length > 1 && ( {displayItems.length > 1 && (
@ -155,7 +184,7 @@ export function ArrayInput<T extends Record<string, any>>({
<CircleMinusIcon /> <CircleMinusIcon />
</Button> </Button>
)} )}
{index === displayItems.length - 1 && ( {(isReverse ? index === 0 : index === displayItems.length - 1) && (
<Button <Button
variant='ghost' variant='ghost'
size='icon' size='icon'

View File

@ -0,0 +1,15 @@
'use client';
import { icons as FlagPack } from '@iconify-json/flagpack';
import { icons as Mdi } from '@iconify-json/mdi';
import { icons as Uil } from '@iconify-json/uil';
import { addCollection, Icon as Iconify, IconProps } from '@iconify/react';
addCollection(FlagPack);
addCollection(Mdi);
addCollection(Uil);
export function Icon(props: IconProps) {
return <Iconify {...props} />;
}

View File

@ -0,0 +1,99 @@
import { Input } from '@workspace/ui/components/input';
import { Label } from '@workspace/ui/components/label';
import { cn } from '@workspace/ui/lib/utils';
import { Upload } from 'lucide-react';
import { useState } from 'react';
type ReturnType = 'base64' | 'file';
interface UploadImageProps {
onChange: (value: string | File) => void;
returnType?: ReturnType;
id?: string;
children?: React.ReactNode;
className?: string;
}
export const UploadImage = ({
onChange,
returnType = 'base64',
id = 'image-upload',
children,
className,
}: UploadImageProps) => {
const [isDragging, setIsDragging] = useState(false);
const toBase64 = (file: File): Promise<string> => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);
});
};
const handleImageUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
try {
if (returnType === 'base64') {
const base64 = await toBase64(file);
onChange(base64);
} else {
onChange(file);
}
} catch (error) {
console.error(error);
}
};
const handleDragOver = (e: React.DragEvent<HTMLLabelElement>) => {
e.preventDefault();
setIsDragging(true);
};
const handleDragLeave = (e: React.DragEvent<HTMLLabelElement>) => {
e.preventDefault();
setIsDragging(false);
};
const handleDrop = async (e: React.DragEvent<HTMLLabelElement>) => {
e.preventDefault();
setIsDragging(false);
const file = e.dataTransfer.files?.[0];
if (!file) return;
try {
if (returnType === 'base64') {
const base64 = await toBase64(file);
onChange(base64);
} else {
onChange(file);
}
} catch (error) {
console.error(error);
}
};
return (
<>
<Input type='file' accept='image/*' className='hidden' id={id} onChange={handleImageUpload} />
<Label
htmlFor={id}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
className={cn(
'cursor-pointer',
!children && 'flex items-center justify-center rounded-lg border-2 border-dashed p-4',
isDragging && 'border-primary bg-muted/50',
className,
)}
>
{children || <Upload />}
</Label>
</>
);
};