feat: migrate frontend to Astro + expand AI moderation + backend admin/runtime config

Frontend:
- migrate from Vite to Astro (astro.config.mjs, pages/, layouts/)
- add admin panel, settings page, command palette, error boundary
- refactor App.tsx, MascotChatbot, Sidebar, Header, DashboardLayout
- update API client, WebSocket, auth, dashboard features

Backend:
- add admin module and config routes
- refactor middlewares, Redis connection, WebSocket server/bridge
- add runtime config loader

Discord Gateway:
- refactor AI moderation: circuit breaker, concurrency limiter, fallback processor
- add media analysis client, Seaxng search, user profile learner
- add new drizzle migration

Shared:
- extend database schema, add new config fields
This commit is contained in:
asepharyana
2026-07-02 00:02:41 +07:00
parent d5c22a3959
commit d59b59a7a7
91 changed files with 11165 additions and 674 deletions
@@ -38,6 +38,7 @@ export function MascotImage({
const sizeClass = sizeMap[size];
const chatSizeClass = chatSizeMap[size];
const [isVisible, setIsVisible] = useState(false);
const [imgError, setImgError] = useState(false);
useEffect(() => {
if (showChat && chatMessage) {
@@ -51,13 +52,20 @@ export function MascotImage({
return (
<div className="relative inline-block">
<motion.img
src="https://raw.githubusercontent.com/IMPHNEN/imphnen-frontend-service/develop/apps/dimentorin/public/image/mascot-1.png"
alt="Mascot"
className={`object-contain drop-shadow-md ${sizeClass} ${className}`}
whileHover={{ scale: 1.05 }}
transition={{ type: "spring", stiffness: 300, damping: 30 }}
/>
{imgError ? (
<div className={`flex items-center justify-center ${sizeClass} bg-muted/30 rounded-xl`}>
<MessageCircle className="h-6 w-6 text-muted-foreground/50" />
</div>
) : (
<motion.img
src="https://raw.githubusercontent.com/IMPHNEN/imphnen-frontend-service/develop/apps/dimentorin/public/image/mascot-1.png"
alt="Mascot"
className={`object-contain drop-shadow-md ${sizeClass} ${className}`}
whileHover={{ scale: 1.05 }}
transition={{ type: "spring", stiffness: 300, damping: 30 }}
onError={() => setImgError(true)}
/>
)}
{/* Floating Chat Bubble */}
{isVisible && chatMessage && (
@@ -72,7 +80,7 @@ export function MascotImage({
{/* Chat bubble */}
<div className="bg-primary/90 text-primary-foreground rounded-xl px-4 py-2.5 shadow-lg backdrop-blur-sm border border-primary/30">
<div className="flex items-start gap-2">
<MessageCircle className="h-4 w-4 shrink-0 mt-0.5 text-white/80" />
<MessageCircle className="h-4 w-4 shrink-0 mt-0.5 text-primary-foreground/80" />
<p className="text-xs leading-relaxed font-medium line-clamp-3">
{chatMessage}
</p>