mirror of
https://github.com/coaidev/coai.git
synced 2025-05-18 20:40:13 +09:00
chore: community awareness banners
This commit is contained in:
parent
0398b8f724
commit
1fcde51da4
@ -161,3 +161,64 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.community-banner-container {
|
||||
width: 100%;
|
||||
padding: 0 1.5rem;
|
||||
|
||||
@media (max-width: 940px) {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.community-banner {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
height: max-content;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: var(--radius);
|
||||
background: hsl(var(--background));
|
||||
box-shadow: 0.5rem 0.5rem 1rem 0 var(--shadow);
|
||||
user-select: none;
|
||||
margin: 0 auto;
|
||||
max-width: calc(100% - 1rem);
|
||||
}
|
||||
|
||||
.banner-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.banner-message {
|
||||
h3 {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 0.875rem;
|
||||
color: hsl(var(--text-secondary));
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.banner-actions {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
justify-content: flex-end;
|
||||
|
||||
.discord-link {
|
||||
white-space: nowrap;
|
||||
min-width: max-content;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.banner-actions {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
95
app/src/components/admin/CommunityBanner.tsx
Normal file
95
app/src/components/admin/CommunityBanner.tsx
Normal file
@ -0,0 +1,95 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useState, useEffect } from "react";
|
||||
import { X, MessageCircle } from "lucide-react";
|
||||
import { setBooleanMemory, getBooleanMemory } from "@/utils/memory.ts";
|
||||
import { Button } from "@/components/ui/button.tsx";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
} from "@/components/ui/alert-dialog.tsx";
|
||||
|
||||
const DISCORD_LINK = "https://discord.gg/tw9N8GChKp";
|
||||
|
||||
function CommunityBanner() {
|
||||
const { t } = useTranslation();
|
||||
const [visible, setVisible] = useState(true);
|
||||
const [showConfirm, setShowConfirm] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const isBannerClosed = getBooleanMemory("community_banner_closed", false);
|
||||
if (isBannerClosed) {
|
||||
setVisible(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleClose = () => {
|
||||
setShowConfirm(true);
|
||||
};
|
||||
|
||||
const confirmClose = () => {
|
||||
setBooleanMemory("community_banner_closed", true);
|
||||
setVisible(false);
|
||||
setShowConfirm(false);
|
||||
};
|
||||
|
||||
const handleDiscordClick = () => {
|
||||
window.open(DISCORD_LINK, "_blank");
|
||||
};
|
||||
|
||||
if (!visible) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="community-banner-container">
|
||||
<div className="community-banner">
|
||||
<div className="banner-content">
|
||||
<div className="banner-message">
|
||||
<h3 className="text-lg font-semibold">{t("admin.join-community")}</h3>
|
||||
<p className="text-sm text-muted-foreground">{t("admin.community-description")}</p>
|
||||
</div>
|
||||
<div className="banner-actions">
|
||||
<Button
|
||||
variant="default"
|
||||
className="discord-link"
|
||||
onClick={handleDiscordClick}
|
||||
>
|
||||
<MessageCircle className="mr-2 h-4 w-4" />
|
||||
{t("admin.community-join-button")}
|
||||
</Button>
|
||||
<Button variant="ghost" size="icon" onClick={handleClose} className="close-button">
|
||||
<X className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AlertDialog open={showConfirm} onOpenChange={setShowConfirm}>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{t("admin.community-confirm-close")}</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{t("admin.community-banner-confirm")}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel onClick={handleDiscordClick}>
|
||||
{t("admin.community-stay")}
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={confirmClose}>
|
||||
{t("admin.community-close")}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default CommunityBanner;
|
@ -507,6 +507,13 @@
|
||||
"default-password": "密码修改提示",
|
||||
"default-password-prompt": "您的管理员密码为默认密码,为了您的账号安全,请尽快修改密码。(前往后台管理 - 系统设置 - 修改 Root 密码)",
|
||||
"chatnio-format-only": "此格式为 Chat Nio 独有格式",
|
||||
"join-community": "🎉 加入社区",
|
||||
"community-description": "🥳 我们在 Discord 创建了新的用户交流社区,您现在可以加入我们的 Discord 社区与我们进行交流与反馈,或是获取项目的最新动态! 🥳",
|
||||
"community-join-button": "加入我们",
|
||||
"community-confirm-close": "您确定要关闭此公告吗?",
|
||||
"community-banner-confirm": "您真的不考虑加入社区与我们一起共建项目或是获取项目的更新与动态吗?该横幅在不清除浏览器缓存的情况下仅会显示一次",
|
||||
"community-stay": "加入我们",
|
||||
"community-close": "确认关闭",
|
||||
"identity": {
|
||||
"normal": "普通用户",
|
||||
"api_paid": "其他付费用户",
|
||||
|
@ -724,7 +724,14 @@
|
||||
"used-at": "Collection time",
|
||||
"used-username": "Claim User",
|
||||
"is-subscribed-tips": "Subscription judgment logic: There is a subscription tier and the subscription period has not expired",
|
||||
"expired-at": "Subscription Expiration Time"
|
||||
"expired-at": "Subscription Expiration Time",
|
||||
"join-community": "🎉 Join the Community",
|
||||
"community-description": "🥳 We've created a new user community in Discord, and you can now join our Discord community to chat and give feedback, or get updates on your projects! 🥳",
|
||||
"community-join-button": "Join Us",
|
||||
"community-confirm-close": "Are you sure you want to close this announcement?",
|
||||
"community-banner-confirm": "Do you really not consider joining the community to build projects with us or to get updates and updates on projects? The banner will only be displayed once without clearing the browser cache",
|
||||
"community-stay": "Join Us",
|
||||
"community-close": "Confirm Close"
|
||||
},
|
||||
"mask": {
|
||||
"title": "Mask Settings",
|
||||
|
@ -725,7 +725,14 @@
|
||||
"used-at": "乗車時間",
|
||||
"used-username": "ユーザーを請求する",
|
||||
"is-subscribed-tips": "サブスクリプション判断ロジック:サブスクリプションティアがあり、サブスクリプション期間が満了していません",
|
||||
"expired-at": "サブスクリプションの有効期限"
|
||||
"expired-at": "サブスクリプションの有効期限",
|
||||
"join-community": "コミュニティ🎉 に参加する",
|
||||
"community-description": "Discordに新しいユーザーコミュニティを作成し🥳ました。Discordコミュニティに参加してチャットやフィードバックを提供したり、プロジェクトの最新情報を入手したりできるようになりました! 🥳",
|
||||
"community-join-button": "ぜひご参加ください",
|
||||
"community-confirm-close": "このお知らせを閉じてもよろしいですか?",
|
||||
"community-banner-confirm": "私たちと一緒にプロジェクトを構築したり、プロジェクトの最新情報やアップデートを入手したりするために、コミュニティに参加することを本当に考えていませんか?バナーはブラウザのキャッシュをクリアせずに一度だけ表示されます",
|
||||
"community-stay": "ぜひご参加ください",
|
||||
"community-close": "終了の確認"
|
||||
},
|
||||
"mask": {
|
||||
"title": "プリセット設定",
|
||||
|
@ -725,7 +725,14 @@
|
||||
"used-at": "Время награждения",
|
||||
"used-username": "Получить пользователя",
|
||||
"is-subscribed-tips": "Логика суждения о подписке: существует уровень подписки, и период подписки не истек",
|
||||
"expired-at": "Срок действия подписки"
|
||||
"expired-at": "Срок действия подписки",
|
||||
"join-community": "🎉 Присоединиться к сообществу",
|
||||
"community-description": "🥳 Мы создали новое сообщество пользователей в Discord, и теперь вы можете присоединиться к нашему сообществу Discord, чтобы общаться и оставлять отзывы или получать новости о своих проектах! 🥳",
|
||||
"community-join-button": "Присоединяйтесь к нам",
|
||||
"community-confirm-close": "Вы уверены, что хотите закрыть это объявление?",
|
||||
"community-banner-confirm": "Вы действительно не задумываетесь о том, чтобы присоединиться к сообществу для создания проектов с нами или для получения обновлений и обновлений по проектам? Баннер будет отображаться только один раз без очистки кэша браузера",
|
||||
"community-stay": "Присоединяйтесь к нам",
|
||||
"community-close": "Подтверждение выхода"
|
||||
},
|
||||
"mask": {
|
||||
"title": "Настройки маски",
|
||||
|
@ -780,7 +780,14 @@
|
||||
"title": "服務日誌",
|
||||
"console": "控制台",
|
||||
"consoleLength": "日誌數量"
|
||||
}
|
||||
},
|
||||
"join-community": "🎉 加入社區",
|
||||
"community-description": "🥳 我們在Discord 創建了一個新的用戶交流社區,您現在可以加入我們的Discord 社群與我們進行交流與回饋,或是獲取專案的最新動態! 🥳",
|
||||
"community-join-button": "加入我們",
|
||||
"community-confirm-close": "您確定要關閉此公告嗎?",
|
||||
"community-banner-confirm": "您真的不考慮加入社區與我們一起共建項目或是獲取項目的更新與動態嗎?該橫幅在不清除瀏覽器快取的情況下僅會顯示一次",
|
||||
"community-stay": "加入我們",
|
||||
"community-close": "確認關閉"
|
||||
},
|
||||
"mask": {
|
||||
"title": "預設設定",
|
||||
|
@ -1,9 +1,11 @@
|
||||
import InfoBox from "@/components/admin/InfoBox.tsx";
|
||||
import ChartBox from "@/components/admin/ChartBox.tsx";
|
||||
import CommunityBanner from "@/components/admin/CommunityBanner.tsx";
|
||||
|
||||
function DashBoard() {
|
||||
return (
|
||||
<div className={`dashboard`}>
|
||||
<CommunityBanner />
|
||||
<InfoBox />
|
||||
<ChartBox />
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user