feat: Add AI subtask reproduction script, refactor Admin MCP settings UI, update Vite config, and add i18n gamification rules.
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-12-15 16:20:47 +01:00
parent bc40969ad7
commit e8d9d0c686
13 changed files with 233 additions and 70 deletions
@@ -0,0 +1,21 @@
{
"gamification": {
"rules": {
"title": "Gamification Rules",
"xpSystem": "XP System",
"levelRequirements": "Level Requirements",
"actions": "Actions & Rewards",
"level": "Level {{level}}",
"xp": "{{xp}} XP",
"action": "Action",
"points": "Points",
"createTask": "Create Task",
"createSubtask": "Create Subtask",
"updateTask": "Update Task",
"completeTask": "Complete Task (On Time)",
"completeTaskLate": "Complete Task (Late)",
"aiAction": "Use AI Feature",
"dailyStreak": "Daily Streak Bonus"
}
}
}
+8 -1
View File
@@ -37,6 +37,10 @@ export default function AdminSettings() {
<Settings className="h-4 w-4" />
General & AI
</TabsTrigger>
<TabsTrigger value="mcp" className="flex items-center gap-2">
<Bot className="h-4 w-4" />
MCP Integration
</TabsTrigger>
<TabsTrigger value="audit" className="flex items-center gap-2">
<FileText className="h-4 w-4" />
Audit Logs
@@ -45,10 +49,13 @@ export default function AdminSettings() {
<TabsContent value="settings" className="space-y-6">
<AiSettingsCard />
<McpSettingsCard />
<SMTPSettingsCard />
</TabsContent>
<TabsContent value="mcp">
<McpSettingsCard />
</TabsContent>
<TabsContent value="audit">
<AuditLogsTable />
</TabsContent>
-57
View File
@@ -330,64 +330,7 @@ export default function Settings({ onNavigateToTemplates }: SettingsProps) {
<ShareAccessModal open={isShareAccessOpen} onOpenChange={setIsShareAccessOpen} />
{/* MCP Integration */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Server className="w-5 h-5" />
{t('settings.mcp.title')}
</CardTitle>
<CardDescription>{t('settings.mcp.description')}</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex items-center justify-between">
<div className="space-y-0.5">
<p className="font-medium">{t('settings.mcp.status')}</p>
</div>
<div className="flex items-center gap-2 text-green-500">
<div className="w-2 h-2 rounded-full bg-green-500 animate-pulse" />
<span className="font-medium">{t('settings.mcp.running')}</span>
</div>
</div>
<div className="space-y-2">
<p className="text-sm font-medium">{t('settings.mcp.url')}</p>
<div className="flex gap-2">
<Input readOnly value={`${window.location.protocol}//${window.location.host}/api/mcp/sse`} />
<Button variant="outline" size="icon" onClick={() => copyToClipboard(`${window.location.protocol}//${window.location.host}/api/mcp/sse`)}>
<Copy className="w-4 h-4" />
</Button>
</div>
</div>
<div className="space-y-2">
<p className="text-sm font-medium">{t('settings.mcp.apiKey')}</p>
{user?.apiKey ? (
<div className="flex gap-2">
<Input type="password" readOnly value={user.apiKey} />
{/* Show full key on click/copy only, usually concealed */}
<Button variant="outline" size="icon" onClick={() => copyToClipboard(user.apiKey!)}>
<Copy className="w-4 h-4" />
</Button>
<Button variant="destructive" onClick={() => revokeApiKeyMutation.mutate()} disabled={revokeApiKeyMutation.isPending}>
{t('settings.mcp.revoke')}
</Button>
</div>
) : (
<div className="space-y-2">
<p className="text-sm text-muted-foreground">{t('settings.mcp.noKey')}</p>
<Button onClick={() => generateApiKeyMutation.mutate()} disabled={generateApiKeyMutation.isPending}>
{t('settings.mcp.generate')}
</Button>
</div>
)}
</div>
<div className="bg-muted/50 p-3 rounded-lg text-sm text-muted-foreground">
{t('settings.mcp.instructions')}
</div>
</CardContent>
</Card>