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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,4 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react';
import { Button } from '@workspace/ui/components/button';
import {
Form,
@ -20,6 +19,7 @@ import {
SheetTrigger,
} from '@workspace/ui/components/sheet';
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 { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react';

View File

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

View File

@ -2,7 +2,6 @@
import { getNodeGroupList } from '@/services/admin/server';
import { zodResolver } from '@hookform/resolvers/zod';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button';
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 { ArrayInput } from '@workspace/ui/custom-components/dynamic-Inputs';
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 { cn } from '@workspace/ui/lib/utils';
import { unitConversion } from '@workspace/ui/utils';

View File

@ -7,7 +7,6 @@ import {
getTicketList,
updateTicketStatus,
} from '@/services/admin/ticket';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button';
import {
@ -22,6 +21,7 @@ import { Input } from '@workspace/ui/components/input';
import { Label } from '@workspace/ui/components/label';
import { ScrollArea } from '@workspace/ui/components/scroll-area';
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 { formatDate } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,24 +1,39 @@
{
"actions": "akce",
"app": {
"add": "Přidat",
"appDownloadURL": "URL pro stažení aplikace",
"appIcon": "Ikona aplikace",
"appList": "Seznam aplikací",
"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í",
"cancel": "Zrušit",
"config": "Konfigurace",
"configApp": "Konfigurace aplikace",
"confirm": "Potvrdit",
"confirmDelete": "Potvrdit smazání",
"create": "Vytvořit",
"createApp": "Vytvořit aplikaci",
"createSuccess": "Úspěšně vytvořeno",
"defaultVersion": "Výchozí",
"delete": "Smazat",
"deleteSuccess": "Úspěšně smazáno",
"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",
"editApp": "Upravit aplikaci",
"nameDescription": "Název aplikace, zobrazuje se v seznamu aplikací",
"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",
"updateSuccess": "Úspěšně aktualizováno"
"updateSuccess": "Úspěšně aktualizováno",
"version": "Verze"
},
"cancel": "Zrušit",
"config": {

View File

@ -1,24 +1,39 @@
{
"actions": "Aktionen",
"app": {
"add": "Hinzufügen",
"appDownloadURL": "App-Download-URL",
"appIcon": "App-Symbol",
"appList": "App-Liste",
"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",
"cancel": "Abbrechen",
"config": "Konfiguration",
"configApp": "App-Konfiguration",
"confirm": "Bestätigen",
"confirmDelete": "Löschen bestätigen",
"create": "Erstellen",
"createApp": "App erstellen",
"createSuccess": "Erfolgreich erstellt",
"defaultVersion": "Standard",
"delete": "Löschen",
"deleteSuccess": "Erfolgreich gelöscht",
"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",
"editApp": "App bearbeiten",
"nameDescription": "Anwendungsname, wird in der App-Liste angezeigt",
"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",
"updateSuccess": "Erfolgreich aktualisiert"
"updateSuccess": "Erfolgreich aktualisiert",
"version": "Version"
},
"cancel": "Abbrechen",
"config": {

View File

@ -1,24 +1,39 @@
{
"actions": "Actions",
"app": {
"add": "Add",
"appDownloadURL": "App Download URL",
"appIcon": "App Icon",
"appList": "App List",
"appName": "App Name",
"backupDomains": "Backup Domain List",
"backupDomainsDescription": "Backup domain list for domain resolution, one domain per line",
"batchDelete": "Batch Delete",
"cancel": "Cancel",
"config": "Config",
"configApp": "App Configuration",
"confirm": "Confirm",
"confirmDelete": "Confirm Delete",
"confirmDelete": "Are you sure you want to delete?",
"create": "Create",
"createApp": "Create App",
"createSuccess": "Created successfully",
"defaultVersion": "Default",
"delete": "Delete",
"deleteSuccess": "Deleted successfully",
"deleteWarning": "This action cannot be undone",
"deleteWarning": "Data cannot be recovered after deletion. Please proceed with caution.",
"describeDescription": "Used to describe the application, displayed in the app list",
"description": "Description",
"downloadLink": "Download Link",
"edit": "Edit",
"editApp": "Edit App",
"nameDescription": "Application name, displayed in the app list",
"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",
"updateSuccess": "Updated successfully"
"updateSuccess": "Updated successfully",
"version": "Version"
},
"cancel": "Cancel",
"config": {

View File

@ -1,24 +1,39 @@
{
"actions": "acciones",
"app": {
"add": "Agregar",
"appDownloadURL": "URL de Descarga de la App",
"appIcon": "Icono de la App",
"appList": "Lista de Aplicaciones",
"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",
"cancel": "Cancelar",
"config": "Configuración",
"configApp": "Configuración de la Aplicación",
"confirm": "Confirmar",
"confirmDelete": "Confirmar Eliminación",
"create": "Crear",
"createApp": "Crear App",
"createSuccess": "Creado con éxito",
"defaultVersion": "Versión Predeterminada",
"delete": "Eliminar",
"deleteSuccess": "Eliminado con éxito",
"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",
"editApp": "Editar App",
"nameDescription": "Nombre de la aplicación, se muestra en la lista de aplicaciones",
"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",
"updateSuccess": "Actualizado con éxito"
"updateSuccess": "Actualizado con éxito",
"version": "Versión"
},
"cancel": "Cancelar",
"config": {

View File

@ -1,24 +1,39 @@
{
"actions": "acciones",
"app": {
"add": "Agregar",
"appDownloadURL": "URL de Descarga de la App",
"appIcon": "Ícono de la App",
"appList": "Lista de Aplicaciones",
"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",
"cancel": "Cancelar",
"config": "Configuración",
"configApp": "Configuración de la Aplicación",
"confirm": "Confirmar",
"confirmDelete": "Confirmar Eliminación",
"create": "Crear",
"createApp": "Crear App",
"createSuccess": "Creado exitosamente",
"defaultVersion": "Versión Predeterminada",
"delete": "Eliminar",
"deleteSuccess": "Eliminado exitosamente",
"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",
"editApp": "Editar App",
"nameDescription": "Nombre de la aplicación, se muestra en la lista de aplicaciones",
"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",
"updateSuccess": "Actualizado exitosamente"
"updateSuccess": "Actualizado exitosamente",
"version": "Versión"
},
"cancel": "Cancelar",
"config": {

View File

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

View File

@ -1,24 +1,39 @@
{
"actions": "toiminnot",
"app": {
"add": "Lisää",
"appDownloadURL": "Sovelluksen lataus-URL",
"appIcon": "Sovelluksen kuvake",
"appList": "Sovellusluettelo",
"appName": "Sovelluksen nimi",
"backupDomains": "Varmuuskopiodomainien luettelo",
"backupDomainsDescription": "Varmuuskopiodomainien luettelo domainin resoluutiota varten, yksi domain per rivi",
"batchDelete": "Poista erä",
"cancel": "Peruuta",
"config": "Asetukset",
"configApp": "Sovelluksen asetukset",
"confirm": "Vahvista",
"confirmDelete": "Vahvista poisto",
"create": "Luo",
"createApp": "Luo sovellus",
"createSuccess": "Luotu onnistuneesti",
"defaultVersion": "Oletus",
"delete": "Poista",
"deleteSuccess": "Poistettu onnistuneesti",
"deleteWarning": "Tätä toimintoa ei voi peruuttaa",
"describeDescription": "Käytetään sovelluksen kuvaamiseen, näytetään sovellusluettelossa",
"description": "Kuvaus",
"downloadLink": "Latauslinkki",
"edit": "Muokkaa",
"editApp": "Muokkaa sovellusta",
"nameDescription": "Sovelluksen nimi, näytetään sovellusluettelossa",
"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",
"updateSuccess": "Päivitetty onnistuneesti"
"updateSuccess": "Päivitetty onnistuneesti",
"version": "Versio"
},
"cancel": "Peruuta",
"config": {

View File

@ -1,24 +1,39 @@
{
"actions": "actions",
"app": {
"add": "Ajouter",
"appDownloadURL": "URL de téléchargement de l'application",
"appIcon": "Icône de l'application",
"appList": "Liste des applications",
"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",
"cancel": "Annuler",
"config": "Configuration",
"configApp": "Configuration de l'application",
"confirm": "Confirmer",
"confirmDelete": "Confirmer la suppression",
"create": "Créer",
"createApp": "Créer une application",
"createSuccess": "Créé avec succès",
"defaultVersion": "Par défaut",
"delete": "Supprimer",
"deleteSuccess": "Supprimé avec succès",
"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",
"editApp": "Modifier l'application",
"nameDescription": "Nom de l'application, affiché dans la liste des applications",
"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",
"updateSuccess": "Mis à jour avec succès"
"updateSuccess": "Mis à jour avec succès",
"version": "Version"
},
"cancel": "Annuler",
"config": {

View File

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

View File

@ -1,24 +1,39 @@
{
"actions": "műveletek",
"app": {
"add": "Hozzáadás",
"appDownloadURL": "Alkalmazás letöltési URL",
"appIcon": "Alkalmazás ikon",
"appList": "Alkalmazáslista",
"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",
"cancel": "Mégse",
"config": "Beállítás",
"configApp": "Alkalmazás beállítása",
"confirm": "Megerősítés",
"confirmDelete": "Törlés megerősítése",
"create": "Létrehozás",
"createApp": "Alkalmazás létrehozása",
"createSuccess": "Sikeresen létrehozva",
"defaultVersion": "Alapértelmezett",
"delete": "Törlés",
"deleteSuccess": "Sikeresen törölve",
"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",
"editApp": "Alkalmazás szerkesztése",
"nameDescription": "Alkalmazás neve, megjelenik az alkalmazáslistában",
"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",
"updateSuccess": "Sikeresen frissítve"
"updateSuccess": "Sikeresen frissítve",
"version": "Verzió"
},
"cancel": "Mégse",
"config": {

View File

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

View File

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

View File

@ -1,24 +1,39 @@
{
"actions": "handlinger",
"app": {
"add": "Legg til",
"appDownloadURL": "App Nedlastings-URL",
"appIcon": "App-ikon",
"appList": "Appliste",
"appName": "App-navn",
"backupDomains": "Sikkerhetskopidomener",
"backupDomainsDescription": "Liste over sikkerhetskopidomener for domeneresolusjon, ett domene per linje",
"batchDelete": "Slett i gruppe",
"cancel": "Avbryt",
"config": "Konfigurasjon",
"configApp": "Appkonfigurasjon",
"confirm": "Bekreft",
"confirmDelete": "Bekreft sletting",
"create": "Opprett",
"createApp": "Opprett app",
"createSuccess": "Opprettet vellykket",
"defaultVersion": "Standard",
"delete": "Slett",
"deleteSuccess": "Slettet vellykket",
"deleteWarning": "Denne handlingen kan ikke angres",
"describeDescription": "Brukes til å beskrive applikasjonen, vises i applisten",
"description": "Beskrivelse",
"downloadLink": "Nedlastingslenke",
"edit": "Rediger",
"editApp": "Rediger app",
"nameDescription": "Applikasjonsnavn, vises i applisten",
"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",
"updateSuccess": "Oppdatert vellykket"
"updateSuccess": "Oppdatert vellykket",
"version": "Versjon"
},
"cancel": "Avbryt",
"config": {

View File

@ -1,24 +1,39 @@
{
"actions": "działania",
"app": {
"add": "Dodaj",
"appDownloadURL": "URL pobierania aplikacji",
"appIcon": "Ikona aplikacji",
"appList": "Lista aplikacji",
"appName": "Nazwa aplikacji",
"backupDomains": "Lista domen zapasowych",
"backupDomainsDescription": "Lista domen zapasowych do rozwiązywania domen, jedna domena na linię",
"batchDelete": "Usuń zbiorczo",
"cancel": "Anuluj",
"config": "Konfiguracja",
"configApp": "Konfiguracja aplikacji",
"confirm": "Potwierdź",
"confirmDelete": "Potwierdź usunięcie",
"create": "Utwórz",
"createApp": "Utwórz aplikację",
"createSuccess": "Utworzono pomyślnie",
"defaultVersion": "Domyślna",
"delete": "Usuń",
"deleteSuccess": "Usunięto pomyślnie",
"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",
"editApp": "Edytuj aplikację",
"nameDescription": "Nazwa aplikacji, wyświetlana na liście aplikacji",
"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",
"updateSuccess": "Zaktualizowano pomyślnie"
"updateSuccess": "Zaktualizowano pomyślnie",
"version": "Wersja"
},
"cancel": "Anuluj",
"config": {

View File

@ -1,24 +1,39 @@
{
"actions": "ações",
"app": {
"add": "Adicionar",
"appDownloadURL": "URL de Download do App",
"appIcon": "Ícone do App",
"appList": "Lista de Apps",
"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",
"cancel": "Cancelar",
"config": "Configuração",
"configApp": "Configuração do App",
"confirm": "Confirmar",
"confirmDelete": "Confirmar Exclusão",
"create": "Criar",
"createApp": "Criar App",
"createSuccess": "Criado com sucesso",
"defaultVersion": "Padrão",
"delete": "Excluir",
"deleteSuccess": "Excluído com sucesso",
"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",
"editApp": "Editar App",
"nameDescription": "Nome do aplicativo, exibido na lista de apps",
"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",
"updateSuccess": "Atualizado com sucesso"
"updateSuccess": "Atualizado com sucesso",
"version": "Versão"
},
"cancel": "Cancelar",
"config": {

View File

@ -1,24 +1,39 @@
{
"actions": "acțiuni",
"app": {
"add": "Adaugă",
"appDownloadURL": "URL Descărcare Aplicație",
"appIcon": "Iconiță Aplicație",
"appList": "Listă de aplicații",
"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",
"cancel": "Anulează",
"config": "Configurație",
"configApp": "Configurația aplicației",
"confirm": "Confirmă",
"confirmDelete": "Confirmă Ștergerea",
"create": "Creează",
"createApp": "Creează Aplicație",
"createSuccess": "Creat cu succes",
"defaultVersion": "Implicit",
"delete": "Șterge",
"deleteSuccess": "Șters cu succes",
"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ă",
"editApp": "Editează Aplicație",
"nameDescription": "Numele aplicației, afișat în lista de aplicații",
"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",
"updateSuccess": "Actualizat cu succes"
"updateSuccess": "Actualizat cu succes",
"version": "Versiune"
},
"cancel": "Anulează",
"config": {

View File

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

View File

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

View File

@ -1,24 +1,39 @@
{
"actions": "eylemler",
"app": {
"add": "Ekle",
"appDownloadURL": "Uygulama İndirme URL'si",
"appIcon": "Uygulama Simgesi",
"appList": "Uygulama Listesi",
"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",
"cancel": "İptal",
"config": "Yapılandırma",
"configApp": "Uygulama Yapılandırması",
"confirm": "Onayla",
"confirmDelete": "Silme İşlemini Onayla",
"create": "Oluştur",
"createApp": "Uygulama Oluştur",
"createSuccess": "Başarıyla oluşturuldu",
"defaultVersion": "Varsayılan",
"delete": "Sil",
"deleteSuccess": "Başarıyla silindi",
"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",
"editApp": "Uygulamayı Düzenle",
"nameDescription": "Uygulama adı, uygulama listesinde görüntülenir",
"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ü",
"updateSuccess": "Başarıyla güncellendi"
"updateSuccess": "Başarıyla güncellendi",
"version": "Sürüm"
},
"cancel": "İptal",
"config": {

View File

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

View File

@ -1,24 +1,39 @@
{
"actions": "Hành động",
"app": {
"add": "Thêm",
"appDownloadURL": "URL Tải Ứng Dụng",
"appIcon": "Biểu Tượng Ứng Dụng",
"appList": "Danh sách ứ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",
"cancel": "Hủy",
"config": "Cấu hình",
"configApp": "Cấu hình ứng dụng",
"confirm": "Xác Nhận",
"confirmDelete": "Xác Nhận Xóa",
"create": "Tạo mới",
"createApp": "Tạo Ứng Dụng",
"createSuccess": "Tạo thành công",
"defaultVersion": "Mặc định",
"delete": "Xóa",
"deleteSuccess": "Xóa thành công",
"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",
"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",
"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ý",
"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",
"config": {

View File

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

View File

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

View File

@ -10,7 +10,6 @@
"start": "next start"
},
"dependencies": {
"@iconify/react": "^5.2.0",
"@lottiefiles/dotlottie-react": "^0.12.1",
"@tanstack/react-query": "^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 唯一标识:
import * as announcement from './announcement';
import * as app from './app';
import * as console from './console';
import * as coupon from './coupon';
import * as document from './document';
@ -17,6 +18,7 @@ import * as tool from './tool';
import * as user from './user';
export default {
announcement,
app,
console,
coupon,
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 */
export async function getCurrencyConfig(options?: { [key: string]: any }) {
return request<API.Response & { data?: API.CurrencyConfig }>('/v1/admin/system/currency_config', {

View File

@ -18,21 +18,59 @@ declare namespace API {
updated_at: number;
};
type AppConfig = {
name: string;
domains: string[];
describe: string;
startup_picture: string;
startup_picture_skip_time: number;
};
type Application = {
id: number;
name: string;
platform: string;
subscribe_type: 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 = {
windows: Application[];
mac: Application[];
linux: Application[];
android: Application[];
ios: Application[];
applications: ApplicationResponseInfo[];
};
type ApplicationResponseInfo = {
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 = {
@ -92,11 +130,26 @@ declare namespace API {
};
type CreateApplicationRequest = {
name: string;
platform: 'windows' | 'mac' | 'linux' | 'android' | 'ios';
subscribe_type: string;
icon: string;
name: string;
description: string;
subscribe_type: string;
};
type CreateApplicationVersionRequest = {
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 = {
@ -214,6 +267,10 @@ declare namespace API {
currency_symbol: string;
};
type DefaultAppVersionRequest = {
id: number;
};
type DeleteAnnouncementRequest = {
id: number;
};
@ -222,6 +279,14 @@ declare namespace API {
id: number;
};
type DeleteApplicationVersionRequest = {
id: number;
};
type DeleteAppVersionRequest = {
id: number;
};
type DeleteCouponRequest = {
id: number;
};
@ -333,6 +398,23 @@ declare namespace API {
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 = {
page: number;
size: number;
@ -984,10 +1066,28 @@ declare namespace API {
type UpdateApplicationRequest = {
id: number;
name: string;
subscribe_type: string;
icon: string;
name: string;
description: string;
subscribe_type: string;
};
type UpdateApplicationVersionRequest = {
id: number;
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 = {

View File

@ -2,6 +2,14 @@
/* eslint-disable */
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 */
export async function sendEmailCode(body: API.SendCodeRequest, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.SendCodeResponse }>('/v1/common/send_code', {

View File

@ -10,21 +10,59 @@ declare namespace API {
updated_at: number;
};
type AppConfig = {
name: string;
domains: string[];
describe: string;
startup_picture: string;
startup_picture_skip_time: number;
};
type Application = {
id: number;
name: string;
platform: string;
subscribe_type: 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 = {
windows: Application[];
mac: Application[];
linux: Application[];
android: Application[];
ios: Application[];
applications: ApplicationResponseInfo[];
};
type ApplicationResponseInfo = {
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 = {
@ -113,6 +151,11 @@ declare namespace API {
created_at: number;
};
type GetAppInfoResponse = {
config: AppConfig;
versions: AppVersion[];
};
type GetGlobalConfigResponse = {
site: SiteConfig;
verify: VeifyConfig;

View File

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

View File

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

View File

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

View File

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

View File

@ -2,12 +2,12 @@
import { Display } from '@/components/display';
import { querySubscribeGroupList, querySubscribeList } from '@/services/user/subscribe';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button';
import { Card, CardContent, CardFooter, CardHeader } from '@workspace/ui/components/card';
import { Separator } from '@workspace/ui/components/separator';
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 { useTranslations } from 'next-intl';
import { useState } from 'react';

View File

@ -9,7 +9,6 @@ import {
getUserTicketList,
updateUserTicketStatus,
} from '@/services/user/ticket';
import { Icon } from '@iconify/react';
import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button';
import {
@ -41,6 +40,7 @@ import { Label } from '@workspace/ui/components/label';
import { ScrollArea } from '@workspace/ui/components/scroll-area';
import { Textarea } from '@workspace/ui/components/textarea';
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 { formatDate } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import { queryAnnouncement } from '@/services/user/announcement';
import { Icon } from '@iconify/react';
import { Card } from '@workspace/ui/components/card';
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 { getTranslations } from 'next-intl/server';
import { Empty } from '../empty';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,6 +2,14 @@
/* eslint-disable */
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 */
export async function sendEmailCode(body: API.SendCodeRequest, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.SendCodeResponse }>('/v1/common/send_code', {

View File

@ -10,21 +10,59 @@ declare namespace API {
updated_at: number;
};
type AppConfig = {
name: string;
domains: string[];
describe: string;
startup_picture: string;
startup_picture_skip_time: number;
};
type Application = {
id: number;
name: string;
platform: string;
subscribe_type: 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 = {
windows: Application[];
mac: Application[];
linux: Application[];
android: Application[];
ios: Application[];
applications: ApplicationResponseInfo[];
};
type ApplicationResponseInfo = {
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 = {
@ -113,6 +151,11 @@ declare namespace API {
created_at: number;
};
type GetAppInfoResponse = {
config: AppConfig;
versions: AppVersion[];
};
type GetGlobalConfigResponse = {
site: SiteConfig;
verify: VeifyConfig;

View File

@ -10,21 +10,59 @@ declare namespace API {
updated_at: number;
};
type AppConfig = {
name: string;
domains: string[];
describe: string;
startup_picture: string;
startup_picture_skip_time: number;
};
type Application = {
id: number;
name: string;
platform: string;
subscribe_type: 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 = {
windows: Application[];
mac: Application[];
linux: Application[];
android: Application[];
ios: Application[];
applications: ApplicationResponseInfo[];
};
type ApplicationResponseInfo = {
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 = {

BIN
bun.lockb

Binary file not shown.

View File

@ -21,6 +21,10 @@
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.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",
"@radix-ui/react-accordion": "^1.2.2",
"@radix-ui/react-alert-dialog": "^1.1.4",

View File

@ -1,6 +1,5 @@
'use client';
import { Icon } from '@iconify/react';
import { Button } from '@workspace/ui/components/button';
import {
Command,
@ -11,6 +10,7 @@ import {
CommandList,
} from '@workspace/ui/components/command';
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 { countries, type ICountry } from '@workspace/ui/utils/countries';
import { BoxIcon, Check, ChevronsUpDown } from 'lucide-react';

View File

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