fix(routine): resolove routine blocker logic bug and white screen
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
feat(gamification): add streak bonuses, tooltip, and improved history details fix(ep): resolve double counting ep bug ui: update app icon and translations
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||
@@ -491,21 +490,30 @@ export default function AchievementsPage({ user }: { user: User }) {
|
||||
history.map((event) => (
|
||||
<div key={event.id} className="flex items-center justify-between py-3 border-b last:border-0 hover:bg-muted/50 px-2 rounded-md transition-colors">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`p-2 rounded-full ${event.source === 'task_completion' ? 'bg-green-100 text-green-600 dark:bg-green-900/30 dark:text-green-400' :
|
||||
event.source === 'daily_streak' ? 'bg-orange-100 text-orange-600 dark:bg-orange-900/30 dark:text-orange-400' :
|
||||
'bg-blue-100 text-blue-600 dark:bg-blue-900/30 dark:text-blue-400'
|
||||
<div className={`p-2 rounded-full ${event.source === 'complete_task_late' ? 'bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400' :
|
||||
(event.source === 'task_completion' || event.source === 'complete_task') ? 'bg-green-100 text-green-600 dark:bg-green-900/30 dark:text-green-400' :
|
||||
event.source === 'daily_streak' ? 'bg-orange-100 text-orange-600 dark:bg-orange-900/30 dark:text-orange-400' :
|
||||
'bg-blue-100 text-blue-600 dark:bg-blue-900/30 dark:text-blue-400'
|
||||
}`}>
|
||||
{event.source === 'task_completion' ? <CheckCircle2 className="h-4 w-4" /> :
|
||||
event.source === 'daily_streak' ? <Flame className="h-4 w-4" /> :
|
||||
<Trophy className="h-4 w-4" />}
|
||||
{event.source === 'complete_task_late' ? <Clock className="h-4 w-4" /> :
|
||||
event.source.includes('complete') ? <CheckCircle2 className="h-4 w-4" /> :
|
||||
event.source === 'daily_streak' ? <Flame className="h-4 w-4" /> :
|
||||
<Trophy className="h-4 w-4" />}
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium text-sm">
|
||||
{t(`gamification.source.${event.source}`, { defaultValue: event.source }) as string}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{new Date(event.createdAt).toLocaleString()}
|
||||
{event.details?.taskTitle ? event.details.taskTitle : (t(`gamification.source.${event.source}`, { defaultValue: event.source }) as string)}
|
||||
{event.source === 'complete_task_late' && <span className="ml-2 text-xs text-red-500 font-normal">({t('gamification.source.complete_task_late')})</span>}
|
||||
</p>
|
||||
<div className="text-xs text-muted-foreground flex items-center gap-1">
|
||||
<span>{new Date(event.createdAt).toLocaleString()}</span>
|
||||
{event.details?.taskTitle && (
|
||||
<>
|
||||
<span>•</span>
|
||||
<span>{t(`gamification.source.${event.source}`, { defaultValue: event.source })}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span className="font-bold text-green-600 dark:text-green-400">
|
||||
|
||||
@@ -8,6 +8,8 @@ import { useLocation } from "wouter";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { AuditLogsTable } from "@/components/admin/AuditLogsTable";
|
||||
import { McpSettingsCard } from "@/components/admin/McpSettingsCard";
|
||||
import { RoutineSettingsCard } from "@/components/admin/RoutineSettingsCard";
|
||||
import { Clock } from "lucide-react";
|
||||
|
||||
export default function AdminSettings() {
|
||||
const { t } = useTranslation();
|
||||
@@ -41,6 +43,10 @@ export default function AdminSettings() {
|
||||
<Sparkles className="h-4 w-4" />
|
||||
{t('settings.admin.tabs.ai')}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="routines" className="flex items-center gap-2">
|
||||
<Clock className="h-4 w-4" />
|
||||
{t('settings.admin.tabs.routines', 'Routines')}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="mcp" className="flex items-center gap-2">
|
||||
<Bot className="h-4 w-4" />
|
||||
{t('settings.admin.tabs.mcp')}
|
||||
@@ -59,6 +65,10 @@ export default function AdminSettings() {
|
||||
<AiSettingsCard />
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="routines">
|
||||
<RoutineSettingsCard />
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="mcp">
|
||||
<McpSettingsCard />
|
||||
</TabsContent>
|
||||
|
||||
@@ -38,11 +38,21 @@ export default function FocusRoutinePage() {
|
||||
|
||||
// Handlers
|
||||
const handleComplete = async () => {
|
||||
try {
|
||||
await apiRequest("POST", `/api/user/routine/${type}/complete`);
|
||||
// Invalidate user query to update lastMorningRoutine/lastEveningRoutine
|
||||
await queryClient.invalidateQueries({ queryKey: ["/api/user"] });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
toast({ title: t('routine.error', 'Failed to save progress'), variant: 'destructive' });
|
||||
}
|
||||
|
||||
if (type === 'morning') {
|
||||
setLocation('/focus');
|
||||
} else {
|
||||
triggerConfetti(0.5, 0.5);
|
||||
toast({ title: t('routine.dayComplete', "Day Complete! Great job.") });
|
||||
// For evening, maybe logout or home? Or achievements
|
||||
setLocation('/achievements');
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user