Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| db0d9e003e | |||
| f219c52306 | |||
| 3f7b6d16ed | |||
| 6dbebd152d | |||
| bb3bd7b50c | |||
| fbad3b0e51 | |||
| e551232564 | |||
| bf58f25072 | |||
| 85f55def2e | |||
| f72df3a5e8 | |||
| 48a1b97051 | |||
| 786ba0e41c | |||
| ce3197298d | |||
| 092477b2d3 |
+75
-3
@@ -1,13 +1,85 @@
|
||||
<a name="readme-top"></a>
|
||||
# Changelog
|
||||
|
||||
# [1.0.0-beta.29](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.28...v1.0.0-beta.29) (2025-03-14)
|
||||
# [1.0.0-beta.30](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.29...v1.0.0-beta.30) (2025-03-15)
|
||||
|
||||
|
||||
### ✨ Features
|
||||
|
||||
* **api**: Add CheckoutOrder request and response types, and update user purchase request parameters ([dddc21c](https://github.com/perfect-panel/ppanel-web/commit/dddc21c))
|
||||
* **loading**: Replace loading animation with a simpler spinner and loading text ([b8316bb](https://github.com/perfect-panel/ppanel-web/commit/b8316bb))
|
||||
* **api**: Add CheckoutOrder request and response types, and update user purchase request parameters ([48a1b97](https://github.com/perfect-panel/ppanel-web/commit/48a1b97))
|
||||
* **email**: Add traffic exhaustion template ([bb3bd7b](https://github.com/perfect-panel/ppanel-web/commit/bb3bd7b))
|
||||
* **formatting**: Update differenceInDays function to return whole days or two decimal places ([bf58f25](https://github.com/perfect-panel/ppanel-web/commit/bf58f25))
|
||||
* **global**: Add custom data ([6dbebd1](https://github.com/perfect-panel/ppanel-web/commit/6dbebd1))
|
||||
* **input**: Add minimum value constraint and enhance number handling in EnhancedInput ([ce31972](https://github.com/perfect-panel/ppanel-web/commit/ce31972))
|
||||
* **loading**: Replace loading animation with a simpler spinner and loading text ([f72df3a](https://github.com/perfect-panel/ppanel-web/commit/f72df3a))
|
||||
* **node-form**: Update number input fields to enforce step, min, and max values ([3f7b6d1](https://github.com/perfect-panel/ppanel-web/commit/3f7b6d1))
|
||||
* **payment**: Add isEdit prop to PaymentForm and disable fields when editing ([85f55de](https://github.com/perfect-panel/ppanel-web/commit/85f55de))
|
||||
* **timeline**: Simplify timeline component layout and remove commented-out code ([fbad3b0](https://github.com/perfect-panel/ppanel-web/commit/fbad3b0))
|
||||
|
||||
|
||||
### 🎫 Chores
|
||||
|
||||
* **release**: V1.0.0-beta.27 [skip ci] ([092477b](https://github.com/perfect-panel/ppanel-web/commit/092477b))
|
||||
* **release**: V1.0.0-beta.28 [skip ci] ([786ba0e](https://github.com/perfect-panel/ppanel-web/commit/786ba0e))
|
||||
* Merge branch 'beta' into develop ([f219c52](https://github.com/perfect-panel/ppanel-web/commit/f219c52))
|
||||
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
* **dashboard**: Update date display to use start_time if available ([e551232](https://github.com/perfect-panel/ppanel-web/commit/e551232))
|
||||
|
||||
<a name="readme-top"></a>
|
||||
|
||||
# Changelog
|
||||
|
||||
# [1.0.0-beta.29](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.28...v1.0.0-beta.29) (2025-03-14)
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **api**: Add CheckoutOrder request and response types, and update user purchase request parameters ([dddc21c](https://github.com/perfect-panel/ppanel-web/commit/dddc21c))
|
||||
- **loading**: Replace loading animation with a simpler spinner and loading text ([b8316bb](https://github.com/perfect-panel/ppanel-web/commit/b8316bb))
|
||||
|
||||
<a name="readme-top"></a>
|
||||
|
||||
# Changelog
|
||||
|
||||
# [1.0.0-beta.28](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.27...v1.0.0-beta.28) (2025-03-13)
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **input**: Add minimum value constraint and enhance number handling in EnhancedInput ([94822d9](https://github.com/perfect-panel/ppanel-web/commit/94822d9))
|
||||
|
||||
# [1.0.0-beta.27](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.26...v1.0.0-beta.27) (2025-03-13)
|
||||
|
||||
### ♻ Code Refactoring
|
||||
|
||||
- **payment**: Reconstruct the payment page ([7109472](https://github.com/perfect-panel/ppanel-web/commit/7109472))
|
||||
- Enhance user navigation dropdown ui and styling ([d2732e6](https://github.com/perfect-panel/ppanel-web/commit/d2732e6))
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **cdn**: Add CDN URL configuration and update related references ([0c90733](https://github.com/perfect-panel/ppanel-web/commit/0c90733))
|
||||
- **payment**: Add bank card payment ([7fa3a57](https://github.com/perfect-panel/ppanel-web/commit/7fa3a57))
|
||||
- **subscription**: Improve layout and organization of subscription detail tabs ([e4630f8](https://github.com/perfect-panel/ppanel-web/commit/e4630f8))
|
||||
- **subscription**: Refactor subscription handling and update imports for better organization ([2215c7f](https://github.com/perfect-panel/ppanel-web/commit/2215c7f))
|
||||
|
||||
### 🎫 Chores
|
||||
|
||||
- **merge**: Bump version to 1.0.0-beta.26 and update changelog ([3222016](https://github.com/perfect-panel/ppanel-web/commit/3222016))
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **affiliate**: Update user identifier ([35f92c9](https://github.com/perfect-panel/ppanel-web/commit/35f92c9))
|
||||
- **changelog**: Update change log style ([cfa3fc0](https://github.com/perfect-panel/ppanel-web/commit/cfa3fc0))
|
||||
- **payment**: Add notification URL field to payment management interface ([5c710e1](https://github.com/perfect-panel/ppanel-web/commit/5c710e1))
|
||||
- **payment**: Fix payment related type definitions and update payment method references ([c3138a8](https://github.com/perfect-panel/ppanel-web/commit/c3138a8))
|
||||
- **payment**: Refactor purchaseCheckout usage and remove redundant code ([a5e2079](https://github.com/perfect-panel/ppanel-web/commit/a5e2079))
|
||||
- **payment**: Update checkout type from 'link' to 'url' for consistency ([136a1ab](https://github.com/perfect-panel/ppanel-web/commit/136a1ab))
|
||||
- **payment**: Update payment information ([70d6a38](https://github.com/perfect-panel/ppanel-web/commit/70d6a38))
|
||||
- **payment**: Update payment method update logic to include row data ([6752420](https://github.com/perfect-panel/ppanel-web/commit/6752420))
|
||||
- **purchasing**: Update payment type to lowercase and add optional chaining for discounts ([c06ea49](https://github.com/perfect-panel/ppanel-web/commit/c06ea49))
|
||||
- **ui**: Improve dashboard layout and enhance button functionality; open checkout URLs in a new tab ([fc0da76](https://github.com/perfect-panel/ppanel-web/commit/fc0da76))
|
||||
- **ui**: Multiple display bugs ([f5d8fd3](https://github.com/perfect-panel/ppanel-web/commit/f5d8fd3))
|
||||
|
||||
<a name="readme-top"></a>
|
||||
|
||||
|
||||
@@ -286,31 +286,34 @@ export default function Page() {
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value='template'>
|
||||
<div className='grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3'>
|
||||
{['verify_email_template', 'expiration_email_template', 'maintenance_email_template'].map(
|
||||
(templateKey) => (
|
||||
<Card key={templateKey}>
|
||||
<CardHeader>
|
||||
<CardTitle>{t(`${templateKey}`)}</CardTitle>
|
||||
<CardDescription>
|
||||
{t(`${templateKey}Description`, { after: '{{', before: '}}' })}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<HTMLEditor
|
||||
placeholder={t('inputPlaceholder')}
|
||||
value={data?.config?.[templateKey] as string}
|
||||
onBlur={(value) =>
|
||||
updateConfig('config', {
|
||||
...data?.config,
|
||||
[templateKey]: value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
),
|
||||
)}
|
||||
<div className='grid grid-cols-1 gap-4 md:grid-cols-2'>
|
||||
{[
|
||||
'verify_email_template',
|
||||
'expiration_email_template',
|
||||
'maintenance_email_template',
|
||||
'traffic_exceed_email_template',
|
||||
].map((templateKey) => (
|
||||
<Card key={templateKey}>
|
||||
<CardHeader>
|
||||
<CardTitle>{t(`${templateKey}`)}</CardTitle>
|
||||
<CardDescription>
|
||||
{t(`${templateKey}Description`, { after: '{{', before: '}}' })}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<HTMLEditor
|
||||
placeholder={t('inputPlaceholder')}
|
||||
value={data?.config?.[templateKey] as string}
|
||||
onBlur={(value) =>
|
||||
updateConfig('config', {
|
||||
...data?.config,
|
||||
[templateKey]: value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ interface PaymentFormProps<T> {
|
||||
loading?: boolean;
|
||||
initialValues?: T;
|
||||
onSubmit: (values: T) => Promise<boolean>;
|
||||
isEdit?: boolean;
|
||||
}
|
||||
|
||||
export default function PaymentForm<T>({
|
||||
@@ -53,6 +54,7 @@ export default function PaymentForm<T>({
|
||||
loading,
|
||||
initialValues,
|
||||
onSubmit,
|
||||
isEdit,
|
||||
}: PaymentFormProps<T>) {
|
||||
const t = useTranslations('payment');
|
||||
const { common } = useGlobalStore();
|
||||
@@ -317,6 +319,7 @@ export default function PaymentForm<T>({
|
||||
}}
|
||||
defaultValue={field.value}
|
||||
value={field.value}
|
||||
disabled={isEdit}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
|
||||
@@ -136,6 +136,7 @@ export default function PaymentTable() {
|
||||
actions={{
|
||||
render: (row) => [
|
||||
<PaymentForm<API.UpdatePaymentMethodRequest>
|
||||
isEdit
|
||||
key='edit'
|
||||
trigger={<Button>{t('edit')}</Button>}
|
||||
title={t('editPayment')}
|
||||
|
||||
@@ -362,9 +362,10 @@ export default function NodeForm<T extends { [x: string]: any }>({
|
||||
<EnhancedInput
|
||||
{...field}
|
||||
type='number'
|
||||
placeholder='1-65535'
|
||||
step={1}
|
||||
min={1}
|
||||
max={65535}
|
||||
placeholder='1-65535'
|
||||
onValueChange={(value) => {
|
||||
form.setValue(field.name, value);
|
||||
}}
|
||||
@@ -418,6 +419,9 @@ export default function NodeForm<T extends { [x: string]: any }>({
|
||||
<EnhancedInput
|
||||
{...field}
|
||||
type='number'
|
||||
step={1}
|
||||
min={1}
|
||||
max={65535}
|
||||
placeholder='1-65535'
|
||||
onValueChange={(value) => {
|
||||
form.setValue(field.name, value);
|
||||
@@ -899,6 +903,7 @@ export default function NodeForm<T extends { [x: string]: any }>({
|
||||
{
|
||||
name: 'port',
|
||||
type: 'number',
|
||||
step: 1,
|
||||
min: 1,
|
||||
max: 65535,
|
||||
placeholder: t('form.relayPort'),
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useQuery } from '@tanstack/react-query';
|
||||
import { Label } from '@workspace/ui/components/label';
|
||||
import { Table, TableBody, TableCell, TableRow } from '@workspace/ui/components/table';
|
||||
import { Textarea } from '@workspace/ui/components/textarea';
|
||||
import { JSONEditor } from '@workspace/ui/custom-components/editor';
|
||||
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
|
||||
import { UploadImage } from '@workspace/ui/custom-components/upload-image';
|
||||
import { useTranslations } from 'next-intl';
|
||||
@@ -130,6 +131,49 @@ export default function Site() {
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<Label>{t('customData')}</Label>
|
||||
<p className='text-muted-foreground text-xs'>{t('customDataDescription')}</p>
|
||||
</TableCell>
|
||||
<TableCell className='w-1/2 text-right'>
|
||||
<JSONEditor
|
||||
schema={{
|
||||
type: 'object',
|
||||
additionalProperties: true,
|
||||
properties: {
|
||||
website: { type: 'string', title: 'Website' },
|
||||
contacts: {
|
||||
type: 'object',
|
||||
title: 'Contacts',
|
||||
additionalProperties: true,
|
||||
properties: {
|
||||
email: { type: 'string', title: 'Email' },
|
||||
telephone: { type: 'string', title: 'Telephone' },
|
||||
address: { type: 'string', title: 'Address' },
|
||||
},
|
||||
},
|
||||
community: {
|
||||
type: 'object',
|
||||
title: 'Community',
|
||||
additionalProperties: true,
|
||||
properties: {
|
||||
telegram: { type: 'string', title: 'Telegram' },
|
||||
twitter: { type: 'string', title: 'Twitter' },
|
||||
discord: { type: 'string', title: 'Discord' },
|
||||
instagram: { type: 'string', title: 'Instagram' },
|
||||
linkedin: { type: 'string', title: 'Linkedin' },
|
||||
facebook: { type: 'string', title: 'Facebook' },
|
||||
github: { type: 'string', title: 'Github' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
value={data?.custom_data}
|
||||
onBlur={(value) => updateConfig('custom_data', value)}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
|
||||
@@ -58,8 +58,21 @@ export default function Page() {
|
||||
<Switch
|
||||
defaultChecked={row.getValue('enable')}
|
||||
onCheckedChange={async (checked) => {
|
||||
const {
|
||||
auth_methods,
|
||||
user_devices,
|
||||
enable_balance_notify,
|
||||
enable_login_notify,
|
||||
enable_subscribe_notify,
|
||||
enable_trade_notify,
|
||||
updated_at,
|
||||
created_at,
|
||||
id,
|
||||
...rest
|
||||
} = row.original;
|
||||
await updateUserBasicInfo({
|
||||
...row.original,
|
||||
user_id: id,
|
||||
...rest,
|
||||
enable: checked,
|
||||
} as unknown as API.UpdateUserBasiceInfoRequest);
|
||||
toast.success(t('updateSuccess'));
|
||||
|
||||
@@ -16,6 +16,7 @@ export const useGlobalStore = create<GlobalStore>((set) => ({
|
||||
site_logo: '',
|
||||
keywords: '',
|
||||
custom_html: '',
|
||||
custom_data: '',
|
||||
},
|
||||
verify: {
|
||||
turnstile_site_key: '',
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Stav",
|
||||
"subject": "Předmět",
|
||||
"template": "Šablona",
|
||||
"traffic_exceed_email_template": "Šablona oznámení o překročení provozu",
|
||||
"traffic_exceed_email_templateDescription": "Zástupné symboly {after}.variable{before} budou nahrazeny skutečnými daty. Ujistěte se, že tyto proměnné zachováte.",
|
||||
"verify_email_template": "Šablona ověřovacího e-mailu",
|
||||
"verify_email_templateDescription": "Zástupné symboly {after}.variable{before} budou nahrazeny skutečnými daty. Ujistěte se, že tyto proměnné zachováte.",
|
||||
"whitelistSuffixes": "Povolené přípony",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Zásady ochrany osobních údajů"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Vlastní data",
|
||||
"customDataDescription": "Vlastní data, používaná pro vlastní data webu",
|
||||
"customHtml": "Vlastní HTML",
|
||||
"customHtmlDescription": "Vlastní HTML kód, který bude vložen na konec tagu body na stránce.",
|
||||
"keywords": "Klíčová slova",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Status",
|
||||
"subject": "Betreff",
|
||||
"template": "Vorlage",
|
||||
"traffic_exceed_email_template": "Benachrichtigung über überschreitenden Verkehr",
|
||||
"traffic_exceed_email_templateDescription": "Die Platzhalter {after}.variable{before} werden durch tatsächliche Daten ersetzt. Stellen Sie sicher, dass Sie diese Variablen beibehalten.",
|
||||
"verify_email_template": "E-Mail-Bestätigungsvorlage",
|
||||
"verify_email_templateDescription": "Die Platzhalter {after}.variable{before} werden durch tatsächliche Daten ersetzt. Stellen Sie sicher, dass diese Variablen beibehalten werden.",
|
||||
"whitelistSuffixes": "Whitelist-Suffixe",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Datenschutzrichtlinie"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Benutzerdefinierte Daten",
|
||||
"customDataDescription": "Benutzerdefinierte Daten, die für benutzerdefinierte Daten der Website verwendet werden",
|
||||
"customHtml": "Benutzerdefiniertes HTML",
|
||||
"customHtmlDescription": "Benutzerdefinierter HTML-Code, der am Ende des body-Tags der Seite eingefügt werden soll.",
|
||||
"keywords": "Schlüsselwörter",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Status",
|
||||
"subject": "Subject",
|
||||
"template": "Template",
|
||||
"traffic_exceed_email_template": "Traffic Exceed Notice Template",
|
||||
"traffic_exceed_email_templateDescription": "The {after}.variable{before} placeholders will be replaced with actual data. Ensure to keep these variables.",
|
||||
"verify_email_template": "Verification Email Template",
|
||||
"verify_email_templateDescription": "The {after}.variable{before} placeholders will be replaced with actual data. Ensure to keep these variables.",
|
||||
"whitelistSuffixes": "Whitelist Suffixes",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Privacy Policy"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Custom Data",
|
||||
"customDataDescription": "Custom Data, used for custom data of the site",
|
||||
"customHtml": "Custom HTML",
|
||||
"customHtmlDescription": "Custom HTML code to be injected into the bottom of the site's body tag.",
|
||||
"keywords": "Keywords",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Estado",
|
||||
"subject": "Asunto",
|
||||
"template": "Plantilla",
|
||||
"traffic_exceed_email_template": "Plantilla de Notificación de Exceso de Tráfico",
|
||||
"traffic_exceed_email_templateDescription": "Los marcadores de posición {after}.variable{before} serán reemplazados con datos reales. Asegúrate de mantener estas variables.",
|
||||
"verify_email_template": "Plantilla de Correo Electrónico de Verificación",
|
||||
"verify_email_templateDescription": "Los marcadores de posición {after}.variable{before} serán reemplazados con datos reales. Asegúrese de mantener estas variables.",
|
||||
"whitelistSuffixes": "Sufijos de la lista blanca",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Política de Privacidad"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Datos Personalizados",
|
||||
"customDataDescription": "Datos Personalizados, utilizados para datos personalizados del sitio",
|
||||
"customHtml": "HTML personalizado",
|
||||
"customHtmlDescription": "Código HTML personalizado que se inyectará en la parte inferior de la etiqueta body del sitio.",
|
||||
"keywords": "Palabras clave",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Estado",
|
||||
"subject": "Asunto",
|
||||
"template": "Plantilla",
|
||||
"traffic_exceed_email_template": "Plantilla de Notificación de Exceso de Tráfico",
|
||||
"traffic_exceed_email_templateDescription": "Los marcadores de posición {after}.variable{before} serán reemplazados con datos reales. Asegúrate de mantener estas variables.",
|
||||
"verify_email_template": "Plantilla de Correo Electrónico de Verificación",
|
||||
"verify_email_templateDescription": "Los marcadores de posición {after}.variable{before} serán reemplazados con datos reales. Asegúrate de mantener estas variables.",
|
||||
"whitelistSuffixes": "Sufijos de Lista Blanca",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Política de Privacidad"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Datos Personalizados",
|
||||
"customDataDescription": "Datos Personalizados, utilizados para datos personalizados del sitio",
|
||||
"customHtml": "HTML personalizado",
|
||||
"customHtmlDescription": "Código HTML personalizado que se inyectará al final de la etiqueta body del sitio.",
|
||||
"keywords": "Palabras clave",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "وضعیت",
|
||||
"subject": "موضوع",
|
||||
"template": "الگو",
|
||||
"traffic_exceed_email_template": "الگوی اعلان ترافیک بیش از حد",
|
||||
"traffic_exceed_email_templateDescription": "جایگزینهای {after}.variable{before} با دادههای واقعی خواهد شد. اطمینان حاصل کنید که این متغیرها را حفظ کنید.",
|
||||
"verify_email_template": "قالب ایمیل تأیید",
|
||||
"verify_email_templateDescription": "جایگذاریهای {after}.variable{before} با دادههای واقعی جایگزین خواهند شد. اطمینان حاصل کنید که این متغیرها را حفظ کنید.",
|
||||
"whitelistSuffixes": "پسوندهای لیست سفید",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "سیاست حفظ حریم خصوصی"
|
||||
},
|
||||
"site": {
|
||||
"customData": "دادههای سفارشی",
|
||||
"customDataDescription": "دادههای سفارشی، استفاده شده برای دادههای سفارشی سایت",
|
||||
"customHtml": "HTML سفارشی",
|
||||
"customHtmlDescription": "کد HTML سفارشی که باید در انتهای تگ body سایت وارد شود.",
|
||||
"keywords": "کلمات کلیدی",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Tila",
|
||||
"subject": "Aihe",
|
||||
"template": "Malline",
|
||||
"traffic_exceed_email_template": "Liikenteen Ylitysilmoitusmalli",
|
||||
"traffic_exceed_email_templateDescription": "{after}.variable{before} -paikat korvataan todellisilla tiedoilla. Varmista, että säilytät nämä muuttujat.",
|
||||
"verify_email_template": "Sähköpostin Vahvistusmalli",
|
||||
"verify_email_templateDescription": "Paikkamerkit {after}.variable{before} korvataan todellisilla tiedoilla. Varmista, että pidät nämä muuttujat.",
|
||||
"whitelistSuffixes": "Sallittujen luetteloiden päätteet",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Tietosuojakäytäntö"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Mukautettu tieto",
|
||||
"customDataDescription": "Mukautettu tieto, jota käytetään sivuston mukautettuun tietoon",
|
||||
"customHtml": "Mukautettu HTML",
|
||||
"customHtmlDescription": "Mukautettu HTML-koodi, joka lisätään sivuston body -tagin loppuun.",
|
||||
"keywords": "Avainsanat",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Statut",
|
||||
"subject": "Sujet",
|
||||
"template": "Modèle",
|
||||
"traffic_exceed_email_template": "Modèle de notification de dépassement de trafic",
|
||||
"traffic_exceed_email_templateDescription": "Les espaces réservés {after}.variable{before} seront remplacés par des données réelles. Assurez-vous de conserver ces variables.",
|
||||
"verify_email_template": "Modèle d'Email de Vérification",
|
||||
"verify_email_templateDescription": "Les espaces réservés {after}.variable{before} seront remplacés par des données réelles. Assurez-vous de conserver ces variables.",
|
||||
"whitelistSuffixes": "Suffixes de la liste blanche",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Politique de confidentialité"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Données personnalisées",
|
||||
"customDataDescription": "Données personnalisées, utilisées pour les données personnalisées du site",
|
||||
"customHtml": "HTML personnalisé",
|
||||
"customHtmlDescription": "Code HTML personnalisé à injecter dans le bas de la balise body du site.",
|
||||
"keywords": "Mots-clés",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "स्थिति",
|
||||
"subject": "विषय",
|
||||
"template": "टेम्पलेट",
|
||||
"traffic_exceed_email_template": "ट्रैफिक अधिकता सूचना टेम्पलेट",
|
||||
"traffic_exceed_email_templateDescription": "{after}.variable{before} प्लेसहोल्डर्स को वास्तविक डेटा के साथ प्रतिस्थापित किया जाएगा। सुनिश्चित करें कि इन वेरिएबल्स को बनाए रखें।",
|
||||
"verify_email_template": "सत्यापन ईमेल टेम्पलेट",
|
||||
"verify_email_templateDescription": "{after}.variable{before} प्लेसहोल्डर्स को वास्तविक डेटा से बदला जाएगा। सुनिश्चित करें कि इन वेरिएबल्स को बनाए रखें।",
|
||||
"whitelistSuffixes": "श्वेतसूची प्रत्यय",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "गोपनीयता नीति"
|
||||
},
|
||||
"site": {
|
||||
"customData": "कस्टम डेटा",
|
||||
"customDataDescription": "कस्टम डेटा, साइट के कस्टम डेटा के लिए उपयोग किया जाता है",
|
||||
"customHtml": "कस्टम HTML",
|
||||
"customHtmlDescription": "साइट के bodyैग के नीचे इंजेक्ट करने के लिए कस्टम HTML कोड।",
|
||||
"keywords": "कीवर्ड",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Állapot",
|
||||
"subject": "Tárgy",
|
||||
"template": "Sablon",
|
||||
"traffic_exceed_email_template": "Forgalmi Túllépés Értesítő Sablon",
|
||||
"traffic_exceed_email_templateDescription": "A {after}.variable{before} helyettesítők tényleges adatokkal lesznek helyettesítve. Győződjön meg róla, hogy ezeket a változókat megőrzi.",
|
||||
"verify_email_template": "Ellenőrző Email Sablon",
|
||||
"verify_email_templateDescription": "A {after}.variable{before} helyőrzőket tényleges adatokkal fogjuk helyettesíteni. Ügyeljen arra, hogy ezeket a változókat megtartsa.",
|
||||
"whitelistSuffixes": "Engedélyezett utótagok",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Adatvédelmi irányelvek"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Egyedi adatok",
|
||||
"customDataDescription": "Egyedi adatok, a webhely egyedi adatainak használatára",
|
||||
"customHtml": "Egyedi HTML",
|
||||
"customHtmlDescription": "Egyedi HTML kód, amelyet a webhely bodyímkéjének aljára kell beilleszteni.",
|
||||
"keywords": "Kulcsszavak",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "ステータス",
|
||||
"subject": "件名",
|
||||
"template": "テンプレート",
|
||||
"traffic_exceed_email_template": "トラフィック超過通知テンプレート",
|
||||
"traffic_exceed_email_templateDescription": "{after}と{before}の変数は実際のデータに置き換えられます。これらの変数を保持することを確認してください。",
|
||||
"verify_email_template": "確認メールテンプレート",
|
||||
"verify_email_templateDescription": "{after}.variable{before} のプレースホルダーは実際のデータに置き換えられます。これらの変数を保持してください。",
|
||||
"whitelistSuffixes": "ホワイトリストのサフィックス",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "プライバシーポリシー"
|
||||
},
|
||||
"site": {
|
||||
"customData": "カスタムデータ",
|
||||
"customDataDescription": "サイトのカスタムデータに使用されるカスタムデータ",
|
||||
"customHtml": "カスタムHTML",
|
||||
"customHtmlDescription": "サイトの body タグの下部に挿入されるカスタム HTML コード。",
|
||||
"keywords": "キーワード",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "상태",
|
||||
"subject": "제목",
|
||||
"template": "템플릿",
|
||||
"traffic_exceed_email_template": "트래픽 초과 알림 템플릿",
|
||||
"traffic_exceed_email_templateDescription": "{after}.variable{before} 자리표시는 실제 데이터로 대체됩니다. 이러한 변수를 유지해야 합니다.",
|
||||
"verify_email_template": "이메일 인증 템플릿",
|
||||
"verify_email_templateDescription": "{after}.variable{before} 자리표시는 실제 데이터로 대체됩니다. 이 변수를 반드시 유지하십시오.",
|
||||
"whitelistSuffixes": "허용 목록 접미사",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "개인정보 처리방침"
|
||||
},
|
||||
"site": {
|
||||
"customData": "사용자 정의 데이터",
|
||||
"customDataDescription": "사이트의 사용자 정의 데이터에 사용되는 사용자 정의 데이터",
|
||||
"customHtml": "사용자 정의 HTML",
|
||||
"customHtmlDescription": "사이트의 body그 하단에 삽입될 사용자 정의 HTML 코드입니다.",
|
||||
"keywords": "키워드",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Status",
|
||||
"subject": "Emne",
|
||||
"template": "Mal",
|
||||
"traffic_exceed_email_template": "Varsel om overskridelse av trafikk",
|
||||
"traffic_exceed_email_templateDescription": "Plassholderne {after}.variable{before} vil bli erstattet med faktiske data. Sørg for å beholde disse variablene.",
|
||||
"verify_email_template": "Verifikasjons-e-postmal",
|
||||
"verify_email_templateDescription": "Plassholderne {after}.variable{before} vil bli erstattet med faktiske data. Sørg for å beholde disse variablene.",
|
||||
"whitelistSuffixes": "Hvitelistesuffikser",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Personvernerklæring"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Egendata",
|
||||
"customDataDescription": "Egendata, brukt for egendata på nettstedet",
|
||||
"customHtml": "Egendefinert HTML",
|
||||
"customHtmlDescription": "Egendefinert HTML-kode som skal settes inn i bunnen av nettstedets body-tag.",
|
||||
"keywords": "Nøkkelord",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Status",
|
||||
"subject": "Temat",
|
||||
"template": "Szablon",
|
||||
"traffic_exceed_email_template": "Szablon powiadomienia o przekroczeniu ruchu",
|
||||
"traffic_exceed_email_templateDescription": "Miejsca {after}.variable{before} zostaną zastąpione rzeczywistymi danymi. Upewnij się, że te zmienne są zachowane.",
|
||||
"verify_email_template": "Szablon e-maila weryfikacyjnego",
|
||||
"verify_email_templateDescription": "Elementy zastępcze {after}.variable{before} zostaną zastąpione rzeczywistymi danymi. Upewnij się, że te zmienne zostaną zachowane.",
|
||||
"whitelistSuffixes": "Dozwolone Sufiksy",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Polityka prywatności"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Dane niestandardowe",
|
||||
"customDataDescription": "Dane niestandardowe, używane do niestandardowych danych witryny",
|
||||
"customHtml": "Niestandardowy HTML",
|
||||
"customHtmlDescription": "Niestandardowy kod HTML, który ma być wstrzyknięty na końcu tagu bodyitryny.",
|
||||
"keywords": "Słowa kluczowe",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Status",
|
||||
"subject": "Assunto",
|
||||
"template": "Modelo",
|
||||
"traffic_exceed_email_template": "Modelo de Notificação de Excesso de Tráfego",
|
||||
"traffic_exceed_email_templateDescription": "Os espaços reservados {after}.variable{before} serão substituídos por dados reais. Certifique-se de manter essas variáveis.",
|
||||
"verify_email_template": "Modelo de E-mail de Verificação",
|
||||
"verify_email_templateDescription": "Os marcadores {after}.variable{before} serão substituídos por dados reais. Certifique-se de manter essas variáveis.",
|
||||
"whitelistSuffixes": "Sufixos de Lista Branca",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Política de Privacidade"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Dados Personalizados",
|
||||
"customDataDescription": "Dados personalizados, usados para dados personalizados do site",
|
||||
"customHtml": "HTML Personalizado",
|
||||
"customHtmlDescription": "Código HTML personalizado a ser inserido no final da tag bodyo site.",
|
||||
"keywords": "Palavras-chave",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Stare",
|
||||
"subject": "Subiect",
|
||||
"template": "Șablon",
|
||||
"traffic_exceed_email_template": "Șablon de notificare a depășirii traficului",
|
||||
"traffic_exceed_email_templateDescription": "Plasamentele {after}.variable{before} vor fi înlocuite cu datele reale. Asigurați-vă că păstrați aceste variabile.",
|
||||
"verify_email_template": "Șablon de e-mail pentru verificare",
|
||||
"verify_email_templateDescription": "Locurile rezervate {after}.variable{before} vor fi înlocuite cu date reale. Asigurați-vă că păstrați aceste variabile.",
|
||||
"whitelistSuffixes": "Sufixe pe lista albă",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Politica de confidențialitate"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Date personalizate",
|
||||
"customDataDescription": "Date personalizate, utilizate pentru datele personalizate ale site-ului",
|
||||
"customHtml": "HTML personalizat",
|
||||
"customHtmlDescription": "Cod HTML personalizat care va fi injectat în partea de jos a etichetei body a site-ului.",
|
||||
"keywords": "Cuvinte cheie",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Статус",
|
||||
"subject": "Тема",
|
||||
"template": "Шаблон",
|
||||
"traffic_exceed_email_template": "Шаблон уведомления о превышении трафика",
|
||||
"traffic_exceed_email_templateDescription": "Места {after}.variable{before} будут заменены на фактические данные. Убедитесь, что эти переменные сохранены.",
|
||||
"verify_email_template": "Шаблон письма для подтверждения",
|
||||
"verify_email_templateDescription": "Заполнители {after}.variable{before} будут заменены фактическими данными. Убедитесь, что эти переменные сохранены.",
|
||||
"whitelistSuffixes": "Белый список суффиксов",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Политика конфиденциальности"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Пользовательские данные",
|
||||
"customDataDescription": "Пользовательские данные, используемые для пользовательских данных сайта",
|
||||
"customHtml": "Пользовательский HTML",
|
||||
"customHtmlDescription": "Пользовательский HTML-код, который будет вставлен в конец тега body сайта.",
|
||||
"keywords": "Ключевые слова",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "สถานะ",
|
||||
"subject": "เรื่อง",
|
||||
"template": "แม่แบบ",
|
||||
"traffic_exceed_email_template": "เทมเพลตการแจ้งเตือนการเกินการจราจร",
|
||||
"traffic_exceed_email_templateDescription": "ตัวแปร {after}.variable{before} จะถูกแทนที่ด้วยข้อมูลจริง โปรดตรวจสอบให้แน่ใจว่าได้เก็บตัวแปรเหล่านี้ไว้",
|
||||
"verify_email_template": "เทมเพลตอีเมลยืนยัน",
|
||||
"verify_email_templateDescription": "ตัวแปร {after}.variable{before} จะถูกแทนที่ด้วยข้อมูลจริง โปรดตรวจสอบให้แน่ใจว่าเก็บตัวแปรเหล่านี้ไว้",
|
||||
"whitelistSuffixes": "อนุญาตให้ใช้คำต่อท้าย",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "นโยบายความเป็นส่วนตัว"
|
||||
},
|
||||
"site": {
|
||||
"customData": "ข้อมูลที่กำหนดเอง",
|
||||
"customDataDescription": "ข้อมูลที่กำหนดเอง ใช้สำหรับข้อมูลที่กำหนดเองของเว็บไซต์",
|
||||
"customHtml": "HTML ที่กำหนดเอง",
|
||||
"customHtmlDescription": "รหัส HTML ที่กำหนดเองเพื่อแทรกลงในส่วนล่างของแท็ก body ของเว็บไซต์.",
|
||||
"keywords": "คำสำคัญ",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Durum",
|
||||
"subject": "Konu",
|
||||
"template": "Şablon",
|
||||
"traffic_exceed_email_template": "Trafik Aşım Bildirimi Şablonu",
|
||||
"traffic_exceed_email_templateDescription": "{after}.variable{before} yer tutucuları gerçek verilerle değiştirilecektir. Bu değişkenleri koruduğunuzdan emin olun.",
|
||||
"verify_email_template": "Doğrulama E-posta Şablonu",
|
||||
"verify_email_templateDescription": "{after}.variable{before} yer tutucuları gerçek verilerle değiştirilecektir. Bu değişkenleri koruduğunuzdan emin olun.",
|
||||
"whitelistSuffixes": "Beyaz Liste Sonekleri",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Gizlilik Politikası"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Özel Veri",
|
||||
"customDataDescription": "Özel Veri, sitenin özel verileri için kullanılır",
|
||||
"customHtml": "Özel HTML",
|
||||
"customHtmlDescription": "Site'in body etiketinin altına yerleştirilecek özel HTML kodu.",
|
||||
"keywords": "Anahtar Kelimeler",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Статус",
|
||||
"subject": "Тема",
|
||||
"template": "Шаблон",
|
||||
"traffic_exceed_email_template": "Шаблон сповіщення про перевищення трафіку",
|
||||
"traffic_exceed_email_templateDescription": "Місця для змінних {after}.variable{before} будуть замінені на фактичні дані. Переконайтеся, що ці змінні залишаються.",
|
||||
"verify_email_template": "Шаблон електронного листа для підтвердження",
|
||||
"verify_email_templateDescription": "Заповнювачі {after}.variable{before} будуть замінені на фактичні дані. Переконайтеся, що зберегли ці змінні.",
|
||||
"whitelistSuffixes": "Білий список суфіксів",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Політика конфіденційності"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Користувацькі дані",
|
||||
"customDataDescription": "Користувацькі дані, що використовуються для користувацьких даних сайту",
|
||||
"customHtml": "Користувацький HTML",
|
||||
"customHtmlDescription": "Користувацький HTML-код, який буде вставлено в кінець тегу body сайту.",
|
||||
"keywords": "Ключові слова",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "Trạng thái",
|
||||
"subject": "Chủ đề",
|
||||
"template": "Mẫu",
|
||||
"traffic_exceed_email_template": "Mẫu Thông Báo Vượt Quá Lưu Lượng",
|
||||
"traffic_exceed_email_templateDescription": "Các biến {after}.variable{before} sẽ được thay thế bằng dữ liệu thực tế. Đảm bảo giữ nguyên các biến này.",
|
||||
"verify_email_template": "Mẫu Email Xác Minh",
|
||||
"verify_email_templateDescription": "Các chỗ trống {after}.variable{before} sẽ được thay thế bằng dữ liệu thực tế. Đảm bảo giữ nguyên các biến này.",
|
||||
"whitelistSuffixes": "Danh sách trắng Hậu tố",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "Chính sách bảo mật"
|
||||
},
|
||||
"site": {
|
||||
"customData": "Dữ liệu tùy chỉnh",
|
||||
"customDataDescription": "Dữ liệu tùy chỉnh, được sử dụng cho dữ liệu tùy chỉnh của trang web",
|
||||
"customHtml": "HTML tùy chỉnh",
|
||||
"customHtmlDescription": "Mã HTML tùy chỉnh để được chèn vào cuối thẻ body của trang.",
|
||||
"keywords": "Từ khóa",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "状态",
|
||||
"subject": "主题",
|
||||
"template": "模板",
|
||||
"traffic_exceed_email_template": "流量超限通知模板",
|
||||
"traffic_exceed_email_templateDescription": "{after}和{before}变量将被实际数据替换。请确保保留这些变量。",
|
||||
"verify_email_template": "验证电子邮件模板",
|
||||
"verify_email_templateDescription": "{after}.variable{before} 占位符将被实际数据替换。请确保保留这些变量。",
|
||||
"whitelistSuffixes": "白名单后缀",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "隐私政策"
|
||||
},
|
||||
"site": {
|
||||
"customData": "自定义数据",
|
||||
"customDataDescription": "自定义数据,用于网站的自定义数据",
|
||||
"customHtml": "自定义HTML",
|
||||
"customHtmlDescription": "要注入到网站 body 标签底部的自定义 HTML 代码。",
|
||||
"keywords": "关键词",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"status": "狀態",
|
||||
"subject": "主題",
|
||||
"template": "模板",
|
||||
"traffic_exceed_email_template": "流量超標通知模板",
|
||||
"traffic_exceed_email_templateDescription": "{after}和{before}變量將會被實際數據替換。請確保保留這些變量。",
|
||||
"verify_email_template": "驗證電郵範本",
|
||||
"verify_email_templateDescription": "{after}.variable{before} 佔位符將被實際數據替換。請確保保留這些變數。",
|
||||
"whitelistSuffixes": "白名單後綴",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"title": "私隱政策"
|
||||
},
|
||||
"site": {
|
||||
"customData": "自定義數據",
|
||||
"customDataDescription": "自定義數據,用於網站的自定義數據",
|
||||
"customHtml": "自定義HTML",
|
||||
"customHtmlDescription": "自定義 HTML 代碼,將注入到網站 body 標籤的底部。",
|
||||
"keywords": "關鍵字",
|
||||
|
||||
+7
@@ -1269,6 +1269,13 @@ declare namespace API {
|
||||
site_logo: string;
|
||||
keywords: string;
|
||||
custom_html: string;
|
||||
custom_data: string;
|
||||
};
|
||||
|
||||
type SiteCustomDataContacts = {
|
||||
email: string;
|
||||
telephone: string;
|
||||
address: string;
|
||||
};
|
||||
|
||||
type SortItem = {
|
||||
|
||||
+7
@@ -659,6 +659,13 @@ declare namespace API {
|
||||
site_logo: string;
|
||||
keywords: string;
|
||||
custom_html: string;
|
||||
custom_data: string;
|
||||
};
|
||||
|
||||
type SiteCustomDataContacts = {
|
||||
email: string;
|
||||
telephone: string;
|
||||
address: string;
|
||||
};
|
||||
|
||||
type SortItem = {
|
||||
|
||||
@@ -164,9 +164,7 @@ export default function Content() {
|
||||
<CardHeader className='flex flex-row flex-wrap items-center justify-between gap-2 space-y-0'>
|
||||
<CardTitle className='font-medium'>
|
||||
{item.subscribe.name}
|
||||
<p className='text-foreground/50 mt-1 text-sm'>
|
||||
{formatDate(item.subscribe.created_at)}
|
||||
</p>
|
||||
<p className='text-foreground/50 mt-1 text-sm'>{formatDate(item.start_time)}</p>
|
||||
</CardTitle>
|
||||
<div className='flex flex-wrap gap-2'>
|
||||
<AlertDialog>
|
||||
|
||||
@@ -22,6 +22,7 @@ export const useGlobalStore = create<GlobalStore>((set, get) => ({
|
||||
site_logo: '',
|
||||
keywords: '',
|
||||
custom_html: '',
|
||||
custom_data: '',
|
||||
},
|
||||
verify: {
|
||||
turnstile_site_key: '',
|
||||
|
||||
+7
@@ -659,6 +659,13 @@ declare namespace API {
|
||||
site_logo: string;
|
||||
keywords: string;
|
||||
custom_html: string;
|
||||
custom_data: string;
|
||||
};
|
||||
|
||||
type SiteCustomDataContacts = {
|
||||
email: string;
|
||||
telephone: string;
|
||||
address: string;
|
||||
};
|
||||
|
||||
type SortItem = {
|
||||
|
||||
Vendored
+7
@@ -777,6 +777,13 @@ declare namespace API {
|
||||
site_logo: string;
|
||||
keywords: string;
|
||||
custom_html: string;
|
||||
custom_data: string;
|
||||
};
|
||||
|
||||
type SiteCustomDataContacts = {
|
||||
email: string;
|
||||
telephone: string;
|
||||
address: string;
|
||||
};
|
||||
|
||||
type SortItem = {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ppanel-web",
|
||||
"version": "1.0.0-beta.29",
|
||||
"version": "1.0.0-beta.30",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/perfect-panel/ppanel-web",
|
||||
"bugs": {
|
||||
|
||||
@@ -28,25 +28,25 @@ export const Timeline = ({ data }: { data: TimelineEntry[] }) => {
|
||||
const opacityTransform = useTransform(scrollYProgress, [0, 0.1], [0, 1]);
|
||||
|
||||
return (
|
||||
<div className='w-full bg-white font-sans md:px-10 dark:bg-neutral-950' ref={containerRef}>
|
||||
<div className='mx-auto max-w-7xl px-4 py-20 md:px-8 lg:px-10'>
|
||||
<h2 className='mb-4 max-w-4xl text-lg text-black md:text-4xl dark:text-white'>
|
||||
<div className='w-full font-sans md:px-10' ref={containerRef}>
|
||||
<div className='mx-auto max-w-7xl px-4 py-10 md:px-8 lg:px-10'>
|
||||
{/* <h2 className='mb-4 max-w-4xl text-lg text-black md:text-4xl dark:text-white'>
|
||||
Changelog from my journey
|
||||
</h2>
|
||||
<p className='max-w-sm text-sm text-neutral-700 md:text-base dark:text-neutral-300'>
|
||||
I've been working on Aceternity for the past 2 years. Here's a timeline of my
|
||||
journey.
|
||||
</p>
|
||||
</p> */}
|
||||
</div>
|
||||
|
||||
<div ref={ref} className='relative mx-auto max-w-7xl pb-20'>
|
||||
{data.map((item, index) => (
|
||||
<div key={index} className='flex justify-start pt-10 md:gap-10 md:pt-40'>
|
||||
<div className='sticky top-40 z-40 flex max-w-xs flex-col items-center self-start md:w-full md:flex-row lg:max-w-sm'>
|
||||
<div className='sticky top-40 z-40 flex max-w-xs flex-col items-center self-start whitespace-nowrap md:w-auto md:flex-row lg:max-w-sm'>
|
||||
<div className='absolute left-3 flex h-10 w-10 items-center justify-center rounded-full bg-white md:left-3 dark:bg-black'>
|
||||
<div className='h-4 w-4 rounded-full border border-neutral-300 bg-neutral-200 p-2 dark:border-neutral-700 dark:bg-neutral-800' />
|
||||
</div>
|
||||
<h3 className='hidden text-xl font-bold text-neutral-500 md:block md:pl-20 md:text-5xl dark:text-neutral-500'>
|
||||
<h3 className='hidden text-xl font-bold text-neutral-500 md:block md:pl-20 md:text-xl dark:text-neutral-500'>
|
||||
{item.title}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
@@ -28,6 +28,6 @@ export function formatDate(date?: Date | number, showTime: boolean = true) {
|
||||
export function differenceInDays(dateLeft: Date | number, dateRight: Date | number) {
|
||||
const diffInMs = differenceInMilliseconds(dateLeft, dateRight);
|
||||
const diffInDays = diffInMs / (1000 * 60 * 60 * 24);
|
||||
if (diffInDays % 1 === 0) return diffInDays;
|
||||
return Number(diffInDays.toFixed(1));
|
||||
if (diffInDays >= 1) return diffInDays.toFixed(0);
|
||||
return Number(diffInDays.toFixed(2));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user