Add distributor announcement feed

This commit is contained in:
abingyyds committed 2026-04-24 18:05:00 +08:00
1 parent 0cc3b941c5
commit 7a142e4845
3 files changed
+36

No files matched your search

+3
View File
@@ -84,6 +84,9 @@
"dashboard.redeem": "Redeem", "dashboard.redeem": "Redeem",
"dashboard.redeemSuccess": "Code redeemed successfully!", "dashboard.redeemSuccess": "Code redeemed successfully!",
"dashboard.quickLinks": "Quick Links", "dashboard.quickLinks": "Quick Links",
"dashboard.announcements": "Announcements",
"dashboard.announcementsDesc": "Latest updates from the site owner",
"dashboard.notice": "Notice",
"dashboard.apiKeys": "API Keys", "dashboard.apiKeys": "API Keys",
"dashboard.manageKeys": "Manage your keys", "dashboard.manageKeys": "Manage your keys",
"dashboard.packages": "Packages", "dashboard.packages": "Packages",
+3
View File
@@ -84,6 +84,9 @@
"dashboard.redeem": "兑换", "dashboard.redeem": "兑换",
"dashboard.redeemSuccess": "兑换码兑换成功!", "dashboard.redeemSuccess": "兑换码兑换成功!",
"dashboard.quickLinks": "快捷入口", "dashboard.quickLinks": "快捷入口",
"dashboard.announcements": "公告通知",
"dashboard.announcementsDesc": "站点管理员发布的最新消息",
"dashboard.notice": "通知",
"dashboard.apiKeys": "API 密钥", "dashboard.apiKeys": "API 密钥",
"dashboard.manageKeys": "管理您的密钥", "dashboard.manageKeys": "管理您的密钥",
"dashboard.packages": "套餐", "dashboard.packages": "套餐",
+30
View File
@@ -1,6 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Megaphone } from 'lucide-react';
import { useAuth } from '../context/AuthContext'; import { useAuth } from '../context/AuthContext';
import { import {
getUserUsage, getUserUsage,
@@ -174,6 +175,9 @@ export default function Dashboard() {
); );
const hasCustomCommissionRate = const hasCustomCommissionRate =
currentCommissionRate > defaultCommissionRate + 1e-8; currentCommissionRate > defaultCommissionRate + 1e-8;
const announcements = Array.isArray(site?.announcements)
? site.announcements.filter((item) => item?.content)
: (site?.announcement ? [{ content: site.announcement, publish_date: '' }] : []);
const handleWithdraw = async () => { const handleWithdraw = async () => {
const amount = Number.parseFloat(withdrawAmount); const amount = Number.parseFloat(withdrawAmount);
@@ -311,6 +315,32 @@ export default function Dashboard() {
<p className="text-sm text-page-secondary">{t('dashboard.manageDesc')}</p> <p className="text-sm text-page-secondary">{t('dashboard.manageDesc')}</p>
</div> </div>
{announcements.length > 0 && (
<div className="glass rounded-2xl p-5 mb-8 border border-brand-500/20">
<div className="flex items-center gap-2 mb-4">
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-brand-500/15 text-page-link">
<Megaphone size={17} />
</div>
<div>
<h2 className="text-base font-semibold text-page">{t('dashboard.announcements')}</h2>
<p className="text-xs text-page-muted">{t('dashboard.announcementsDesc')}</p>
</div>
</div>
<div className="space-y-3">
{announcements.slice(0, 10).map((item, index) => (
<div key={`${item.publish_date || 'notice'}-${index}`} className="flex gap-3 rounded-xl bg-page-surface/60 p-3">
<div className="shrink-0 rounded-full border border-brand-500/20 bg-brand-500/10 px-3 py-1 text-xs font-medium text-page-link">
{item.publish_date || t('dashboard.notice')}
</div>
<p className="min-w-0 whitespace-pre-wrap text-sm leading-6 text-page-secondary">
{item.content}
</p>
</div>
))}
</div>
</div>
)}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-10"> <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-10">
<div className="glass rounded-2xl p-6"> <div className="glass rounded-2xl p-6">
<p className="text-sm text-page-secondary mb-2">{t('dashboard.balance')}</p> <p className="text-sm text-page-secondary mb-2">{t('dashboard.balance')}</p>