Compare commits

...

6 Commits

Author SHA1 Message Date
semantic-release-bot a76471a806 🔖 chore(release): v1.1.4 [skip ci]
## [1.1.4](https://github.com/perfect-panel/ppanel-web/compare/v1.1.3...v1.1.4) (2025-07-25)

### 🐛 Bug Fixes

* **locales**: Simplify "show" label in subscription localization files ([d53a006](https://github.com/perfect-panel/ppanel-web/commit/d53a006))
* **order**: Preserve last successful order on error during order creation ([2fb98be](https://github.com/perfect-panel/ppanel-web/commit/2fb98be))
* **subscribe**: Filter out hidden items in subscription list display ([634be37](https://github.com/perfect-panel/ppanel-web/commit/634be37))
2025-07-25 14:22:31 +00:00
web d53a00611e 🐛 fix(locales): Simplify "show" label in subscription localization files 2025-07-25 07:18:54 -07:00
web 2fb98be591 🐛 fix(order): Preserve last successful order on error during order creation 2025-07-25 07:07:31 -07:00
web 634be371b1 🐛 fix(subscribe): Filter out hidden items in subscription list display 2025-07-25 07:06:53 -07:00
semantic-release-bot ffa5c86d23 🔖 chore(release): v1.1.3 [skip ci]
## [1.1.3](https://github.com/perfect-panel/ppanel-web/compare/v1.1.2...v1.1.3) (2025-07-24)

### 🐛 Bug Fixes

* **auth**: Implement user redirection to dashboard upon authentication ([f84f98c](https://github.com/perfect-panel/ppanel-web/commit/f84f98c))
2025-07-24 17:13:32 +00:00
web f84f98c80f 🐛 fix(auth): Implement user redirection to dashboard upon authentication 2025-07-24 10:10:31 -07:00
30 changed files with 109 additions and 38 deletions
+16
View File
@@ -1,6 +1,22 @@
<a name="readme-top"></a> <a name="readme-top"></a>
# Changelog # Changelog
## [1.1.4](https://github.com/perfect-panel/ppanel-web/compare/v1.1.3...v1.1.4) (2025-07-25)
### 🐛 Bug Fixes
* **locales**: Simplify "show" label in subscription localization files ([d53a006](https://github.com/perfect-panel/ppanel-web/commit/d53a006))
* **order**: Preserve last successful order on error during order creation ([2fb98be](https://github.com/perfect-panel/ppanel-web/commit/2fb98be))
* **subscribe**: Filter out hidden items in subscription list display ([634be37](https://github.com/perfect-panel/ppanel-web/commit/634be37))
## [1.1.3](https://github.com/perfect-panel/ppanel-web/compare/v1.1.2...v1.1.3) (2025-07-24)
### 🐛 Bug Fixes
* **auth**: Implement user redirection to dashboard upon authentication ([f84f98c](https://github.com/perfect-panel/ppanel-web/commit/f84f98c))
## [1.1.2](https://github.com/perfect-panel/ppanel-web/compare/v1.1.1...v1.1.2) (2025-07-24) ## [1.1.2](https://github.com/perfect-panel/ppanel-web/compare/v1.1.1...v1.1.2) (2025-07-24)
+10 -1
View File
@@ -8,13 +8,22 @@ import LoginLottie from '@workspace/ui/lotties/login.json';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import Image from 'next/legacy/image'; import Image from 'next/legacy/image';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import EmailAuthForm from './email/auth-form'; import EmailAuthForm from './email/auth-form';
export default function Page() { export default function Page() {
const t = useTranslations('auth'); const t = useTranslations('auth');
const { common } = useGlobalStore(); const { common, user } = useGlobalStore();
const { site } = common; const { site } = common;
const router = useRouter();
useEffect(() => {
if (user) {
router.replace('/dashboard');
}
}, [router, user]);
return ( return (
<main className='bg-muted/50 flex h-full min-h-screen items-center'> <main className='bg-muted/50 flex h-full min-h-screen items-center'>
<div className='flex size-full flex-auto flex-col justify-center lg:flex-row'> <div className='flex size-full flex-auto flex-col justify-center lg:flex-row'>
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Limit na nákup/čas", "quota": "Limit na nákup/čas",
"replacement": "Obnovení ceny/krát", "replacement": "Obnovení ceny/krát",
"sell": "Prodej", "sell": "Prodej",
"show": "Zobrazit na hlavní stránce", "show": "Zobrazit",
"sold": "Počet předplatných", "sold": "Počet předplatných",
"subscribe": "Předplatit", "subscribe": "Předplatit",
"subscribeGroup": "Přihlásit se ke skupině", "subscribeGroup": "Přihlásit se ke skupině",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Kaufbeschränkung/pro Einkauf", "quota": "Kaufbeschränkung/pro Einkauf",
"replacement": "Preis pro Zurücksetzung", "replacement": "Preis pro Zurücksetzung",
"sell": "Verkauf", "sell": "Verkauf",
"show": "Startseite anzeigen", "show": "Anzeigen",
"sold": "Abonnentenzahl", "sold": "Abonnentenzahl",
"subscribe": "Abonnieren", "subscribe": "Abonnieren",
"subscribeGroup": "Gruppe abonnieren", "subscribeGroup": "Gruppe abonnieren",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Purchase Limit/Time", "quota": "Purchase Limit/Time",
"replacement": "Reset Price/Time", "replacement": "Reset Price/Time",
"sell": "Sell", "sell": "Sell",
"show": "Home display", "show": "Display",
"sold": "Subscription Count", "sold": "Subscription Count",
"subscribe": "Subscribe", "subscribe": "Subscribe",
"subscribeGroup": "Subscription Group", "subscribeGroup": "Subscription Group",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Límite de compra/vez", "quota": "Límite de compra/vez",
"replacement": "Restablecer precio/vez", "replacement": "Restablecer precio/vez",
"sell": "Venta", "sell": "Venta",
"show": "Mostrar en la página de inicio", "show": "Mostrar",
"sold": "Conteo de Suscripciones", "sold": "Conteo de Suscripciones",
"subscribe": "Suscribirse", "subscribe": "Suscribirse",
"subscribeGroup": "Suscribirse al grupo", "subscribeGroup": "Suscribirse al grupo",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Límite de compra/vez", "quota": "Límite de compra/vez",
"replacement": "Restablecer precio/vez", "replacement": "Restablecer precio/vez",
"sell": "venta", "sell": "venta",
"show": "Mostrar en la página de inicio", "show": "Mostrar",
"sold": "Conteo de Suscripciones", "sold": "Conteo de Suscripciones",
"subscribe": "Suscribirse", "subscribe": "Suscribirse",
"subscribeGroup": "Suscribirse al grupo", "subscribeGroup": "Suscribirse al grupo",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "محدودیت خرید/زمان", "quota": "محدودیت خرید/زمان",
"replacement": "تنظیم مجدد قیمت/زمان", "replacement": "تنظیم مجدد قیمت/زمان",
"sell": "فروش", "sell": "فروش",
"show": "نمایش خانه", "show": "نمایش",
"sold": "تعداد اشتراک", "sold": "تعداد اشتراک",
"subscribe": "اشتراک", "subscribe": "اشتراک",
"subscribeGroup": "گروه اشتراک", "subscribeGroup": "گروه اشتراک",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Ostorajoitus/kerta", "quota": "Ostorajoitus/kerta",
"replacement": "Nollaa hinta/kerta", "replacement": "Nollaa hinta/kerta",
"sell": "myydä", "sell": "myydä",
"show": "Etusivun näyt", "show": "Näytä",
"sold": "Tilausmäärä", "sold": "Tilausmäärä",
"subscribe": "Tilaa", "subscribe": "Tilaa",
"subscribeGroup": "Tilaa ryhmä", "subscribeGroup": "Tilaa ryhmä",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Limite d'achat/par fois", "quota": "Limite d'achat/par fois",
"replacement": "Réinitialiser le prix/par fois", "replacement": "Réinitialiser le prix/par fois",
"sell": "Vente", "sell": "Vente",
"show": "Afficher sur la page d'accueil", "show": "Afficher",
"sold": "Nombre d'abonnements", "sold": "Nombre d'abonnements",
"subscribe": "S'abonner", "subscribe": "S'abonner",
"subscribeGroup": "S'abonner au groupe", "subscribeGroup": "S'abonner au groupe",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "प्रति खरीद सीमा", "quota": "प्रति खरीद सीमा",
"replacement": "मूल्य/प्रति बार रीसेट करें", "replacement": "मूल्य/प्रति बार रीसेट करें",
"sell": "बिक्री", "sell": "बिक्री",
"show": "मुखपृष्ठ पर दिखाएं", "show": "दिखाएं",
"sold": "सदस्यता गणना", "sold": "सदस्यता गणना",
"subscribe": "सदस्यता लें", "subscribe": "सदस्यता लें",
"subscribeGroup": "सदस्यता समूह", "subscribeGroup": "सदस्यता समूह",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Vásárlási korlát/alkalom", "quota": "Vásárlási korlát/alkalom",
"replacement": "Ár visszaállítása/alkalom", "replacement": "Ár visszaállítása/alkalom",
"sell": "eladás", "sell": "eladás",
"show": "Kezdőlap megjelenítése", "show": "Megjelenítés",
"sold": "Előfizetések száma", "sold": "Előfizetések száma",
"subscribe": "Feliratkozás", "subscribe": "Feliratkozás",
"subscribeGroup": "Feliratkozási csoport", "subscribeGroup": "Feliratkozási csoport",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "購入制限/回", "quota": "購入制限/回",
"replacement": "リセット価格/回", "replacement": "リセット価格/回",
"sell": "販売", "sell": "販売",
"show": "ホームページ表示", "show": "表示",
"sold": "サブスクリプション数", "sold": "サブスクリプション数",
"subscribe": "購読", "subscribe": "購読",
"subscribeGroup": "グループを購読する", "subscribeGroup": "グループを購読する",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "구매 제한/회", "quota": "구매 제한/회",
"replacement": "가격 재설정/회", "replacement": "가격 재설정/회",
"sell": "판매", "sell": "판매",
"show": "홈 화면 표시", "show": "표시",
"sold": "구독 수", "sold": "구독 수",
"subscribe": "구독", "subscribe": "구독",
"subscribeGroup": "구독 그룹", "subscribeGroup": "구독 그룹",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Kjøpsgrense/gang", "quota": "Kjøpsgrense/gang",
"replacement": "Tilbakestill pris/gang", "replacement": "Tilbakestill pris/gang",
"sell": "Salg", "sell": "Salg",
"show": "Vis på forsiden", "show": "Vis",
"sold": "Abonnementsantall", "sold": "Abonnementsantall",
"subscribe": "Abonner", "subscribe": "Abonner",
"subscribeGroup": "Abonner på gruppe", "subscribeGroup": "Abonner på gruppe",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Limit zakupu/raz", "quota": "Limit zakupu/raz",
"replacement": "Zresetuj cenę/raz", "replacement": "Zresetuj cenę/raz",
"sell": "Sprzedaż", "sell": "Sprzedaż",
"show": "Pokaż na stronie głównej", "show": "Pokaż",
"sold": "Liczba subskrypcji", "sold": "Liczba subskrypcji",
"subscribe": "Subskrybuj", "subscribe": "Subskrybuj",
"subscribeGroup": "Subskrybuj grupę", "subscribeGroup": "Subskrybuj grupę",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Limite de compra/vez", "quota": "Limite de compra/vez",
"replacement": "Redefinir preço/vez", "replacement": "Redefinir preço/vez",
"sell": "venda", "sell": "venda",
"show": "Exibição na página inicial", "show": "Exibir",
"sold": "Contagem de Assinaturas", "sold": "Contagem de Assinaturas",
"subscribe": "Inscrever-se", "subscribe": "Inscrever-se",
"subscribeGroup": "Inscrever-se no grupo", "subscribeGroup": "Inscrever-se no grupo",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Limită de achiziție/pe tranzacție", "quota": "Limită de achiziție/pe tranzacție",
"replacement": "Resetare preț/pe utilizare", "replacement": "Resetare preț/pe utilizare",
"sell": "Vânzare", "sell": "Vânzare",
"show": "Afișare pe pagina principală", "show": "Afișare",
"sold": "Număr de abonamente", "sold": "Număr de abonamente",
"subscribe": "Abonare", "subscribe": "Abonare",
"subscribeGroup": "Abonare grup", "subscribeGroup": "Abonare grup",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Лимит/раз", "quota": "Лимит/раз",
"replacement": "Сбросить цену/раз", "replacement": "Сбросить цену/раз",
"sell": "Продажа", "sell": "Продажа",
"show": "Показать на главной странице", "show": "Показать",
"sold": "Количество подписок", "sold": "Количество подписок",
"subscribe": "Подписаться", "subscribe": "Подписаться",
"subscribeGroup": "Подписаться на группу", "subscribeGroup": "Подписаться на группу",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "จำกัดการซื้อ/ครั้ง", "quota": "จำกัดการซื้อ/ครั้ง",
"replacement": "รีเซ็ตราคา/ครั้ง", "replacement": "รีเซ็ตราคา/ครั้ง",
"sell": "ขาย", "sell": "ขาย",
"show": "แสดงหน้าแรก", "show": "แสดง",
"sold": "จำนวนการสมัครสมาชิก", "sold": "จำนวนการสมัครสมาชิก",
"subscribe": "สมัครสมาชิก", "subscribe": "สมัครสมาชิก",
"subscribeGroup": "สมัครกลุ่ม", "subscribeGroup": "สมัครกลุ่ม",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Kota/satın alma", "quota": "Kota/satın alma",
"replacement": "Fiyatı sıfırla/kez", "replacement": "Fiyatı sıfırla/kez",
"sell": "satış", "sell": "satış",
"show": "Ana sayfada göster", "show": "Göster",
"sold": "Abonelik Sayısı", "sold": "Abonelik Sayısı",
"subscribe": "Abone Ol", "subscribe": "Abone Ol",
"subscribeGroup": "Gruba Abone Ol", "subscribeGroup": "Gruba Abone Ol",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Обмеження на покупку/раз", "quota": "Обмеження на покупку/раз",
"replacement": "Скидання ціни/раз", "replacement": "Скидання ціни/раз",
"sell": "продаж", "sell": "продаж",
"show": "Показати на головній сторінці", "show": "Показати",
"sold": "Кількість підписок", "sold": "Кількість підписок",
"subscribe": "Підписатися", "subscribe": "Підписатися",
"subscribeGroup": "Підписатися на групу", "subscribeGroup": "Підписатися на групу",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "Giới hạn mua/lần", "quota": "Giới hạn mua/lần",
"replacement": "Đặt lại giá/lần", "replacement": "Đặt lại giá/lần",
"sell": "Bán hàng", "sell": "Bán hàng",
"show": "Hiển thị trang chủ", "show": "Hiển thị",
"sold": "Số lượng đăng ký", "sold": "Số lượng đăng ký",
"subscribe": "Đăng ký", "subscribe": "Đăng ký",
"subscribeGroup": "Nhóm đăng ký", "subscribeGroup": "Nhóm đăng ký",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "限购/次", "quota": "限购/次",
"replacement": "重置价格/次", "replacement": "重置价格/次",
"sell": "销售", "sell": "销售",
"show": "首页显示", "show": "显示",
"sold": "订阅数量", "sold": "订阅数量",
"subscribe": "订阅", "subscribe": "订阅",
"subscribeGroup": "订阅组", "subscribeGroup": "订阅组",
+1 -1
View File
@@ -145,7 +145,7 @@
"quota": "限購/次", "quota": "限購/次",
"replacement": "重置價格/次", "replacement": "重置價格/次",
"sell": "銷售", "sell": "銷售",
"show": "首頁顯示", "show": "顯示",
"sold": "訂閱數量", "sold": "訂閱數量",
"subscribe": "訂閱", "subscribe": "訂閱",
"subscribeGroup": "訂閱組", "subscribeGroup": "訂閱組",
@@ -57,6 +57,7 @@ export default function Page() {
)} )}
<div className='grid gap-4 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3'> <div className='grid gap-4 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3'>
{data {data
?.filter((item) => item.show === false)
?.filter((item) => (group ? item.group_id === Number(group) : true)) ?.filter((item) => (group ? item.group_id === Number(group) : true))
?.map((item) => ( ?.map((item) => (
<Card className='flex flex-col' key={item.id}> <Card className='flex flex-col' key={item.id}>
+22 -1
View File
@@ -2,8 +2,29 @@ import { GlobalMap } from '@/components/main/global-map';
import { Hero } from '@/components/main/hero'; import { Hero } from '@/components/main/hero';
import { ProductShowcase } from '@/components/main/product-showcase/index'; import { ProductShowcase } from '@/components/main/product-showcase/index';
import { Stats } from '@/components/main/stats'; import { Stats } from '@/components/main/stats';
import { queryUserInfo } from '@/services/user/user';
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
export default async function Home() {
const Authorization = (await cookies()).get('Authorization')?.value;
if (Authorization) {
let user = null;
try {
user = await queryUserInfo({
skipErrorHandler: true,
Authorization,
}).then((res) => res.data.data);
} catch (error) {
console.log('Token validation failed:', error);
}
if (user) {
redirect('/dashboard');
}
}
export default function Home() {
return ( return (
<main className='container space-y-16'> <main className='container space-y-16'>
<Hero /> <Hero />
+14 -2
View File
@@ -13,7 +13,7 @@ import { Separator } from '@workspace/ui/components/separator';
import { LoaderCircle } from 'lucide-react'; import { LoaderCircle } from 'lucide-react';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useCallback, useEffect, useState, useTransition } from 'react'; import { useCallback, useEffect, useRef, useState, useTransition } from 'react';
import { SubscribeBilling } from './billing'; import { SubscribeBilling } from './billing';
import { SubscribeDetail } from './detail'; import { SubscribeDetail } from './detail';
@@ -33,16 +33,28 @@ export default function Purchase({ subscribe, setSubscribe }: Readonly<PurchaseP
coupon: '', coupon: '',
}); });
const [loading, startTransition] = useTransition(); const [loading, startTransition] = useTransition();
const lastSuccessOrderRef = useRef<any>(null);
const { data: order } = useQuery({ const { data: order } = useQuery({
enabled: !!subscribe?.id, enabled: !!subscribe?.id,
queryKey: ['preCreateOrder', params], queryKey: ['preCreateOrder', params],
queryFn: async () => { queryFn: async () => {
try {
const { data } = await preCreateOrder({ const { data } = await preCreateOrder({
...params, ...params,
subscribe_id: subscribe?.id as number, subscribe_id: subscribe?.id as number,
} as API.PurchaseOrderRequest); } as API.PurchaseOrderRequest);
return data.data; const result = data.data;
if (result) {
lastSuccessOrderRef.current = result;
}
return result;
} catch (error) {
if (lastSuccessOrderRef.current) {
return lastSuccessOrderRef.current;
}
throw error;
}
}, },
}); });
+14 -2
View File
@@ -19,7 +19,7 @@ import { Separator } from '@workspace/ui/components/separator';
import { LoaderCircle } from 'lucide-react'; import { LoaderCircle } from 'lucide-react';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useCallback, useEffect, useState, useTransition } from 'react'; import { useCallback, useEffect, useRef, useState, useTransition } from 'react';
import { SubscribeBilling } from './billing'; import { SubscribeBilling } from './billing';
import { SubscribeDetail } from './detail'; import { SubscribeDetail } from './detail';
@@ -40,16 +40,28 @@ export default function Renewal({ id, subscribe }: Readonly<RenewalProps>) {
user_subscribe_id: id, user_subscribe_id: id,
}); });
const [loading, startTransition] = useTransition(); const [loading, startTransition] = useTransition();
const lastSuccessOrderRef = useRef<any>(null);
const { data: order } = useQuery({ const { data: order } = useQuery({
enabled: !!subscribe.id && open, enabled: !!subscribe.id && open,
queryKey: ['preCreateOrder', params], queryKey: ['preCreateOrder', params],
queryFn: async () => { queryFn: async () => {
try {
const { data } = await preCreateOrder({ const { data } = await preCreateOrder({
...params, ...params,
subscribe_id: subscribe.id, subscribe_id: subscribe.id,
} as API.PurchaseOrderRequest); } as API.PurchaseOrderRequest);
return data.data; const result = data.data;
// 请求成功时保存数据
if (result) {
lastSuccessOrderRef.current = result;
}
return result;
} catch (error) {
if (lastSuccessOrderRef.current) {
return lastSuccessOrderRef.current;
}
}
}, },
}); });
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "ppanel-web", "name": "ppanel-web",
"version": "1.1.2", "version": "1.1.4",
"private": true, "private": true,
"homepage": "https://github.com/perfect-panel/ppanel-web", "homepage": "https://github.com/perfect-panel/ppanel-web",
"bugs": { "bugs": {