Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,25 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/phoenix-logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Quest Leveling System - Gamify Your Life</title>
<meta name="description" content="Transform your daily tasks into epic quests. Earn XP, level up, and achieve your goals with an anime-inspired productivity app." />
<meta name="author" content="Quest Leveling System" />
<title>Phoenix Aura Farming - Gamify Your Life</title>
<meta name="description" content="Transform your daily tasks into epic quests. Earn Aura Points, farm aura, and achieve your goals with an anime-inspired productivity app." />
<meta name="author" content="Phoenix Aura Farming" />

<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=Orbitron:wght@400;500;600;700;800;900&display=swap" rel="stylesheet">

<meta property="og:title" content="Quest Leveling System - Gamify Your Life" />
<meta property="og:description" content="Transform your daily tasks into epic quests. Earn XP, level up, and achieve your goals." />
<meta property="og:title" content="Phoenix Aura Farming - Gamify Your Life" />
<meta property="og:description" content="Transform your daily tasks into epic quests. Earn Aura Points, farm aura, and achieve your goals." />
<meta property="og:type" content="website" />
<meta property="og:image" content="https://lovable.dev/opengraph-image-p98pqg.png" />
<meta property="og:image" content="/phoenix-logo.png" />

<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@lovable_dev" />
<meta name="twitter:image" content="https://lovable.dev/opengraph-image-p98pqg.png" />
<meta name="twitter:site" content="@phoenix_aura" />
<meta name="twitter:image" content="/phoenix-logo.png" />
</head>

<body>
Expand Down
Binary file added frontend/public/phoenix-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Dashboard from './pages/Dashboard';
const queryClient = new QueryClient();

// Google Client ID - Replace with your own
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID || '271595121987-jf5sh78h3ee6q41k13rcjcng4h70df46.apps.googleusercontent.com';
const GOOGLE_CLIENT_ID = '271595121987-jf5sh78h3ee6q41k13rcjcng4h70df46.apps.googleusercontent.com';

// Inner component that uses the store - must be inside BrowserRouter
const AppRoutes = () => {
Expand Down
51 changes: 51 additions & 0 deletions frontend/src/components/PhoenixIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { SVGProps } from 'react';

export const PhoenixIcon = (props: SVGProps<SVGSVGElement>) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
{...props}
>
{/* Phoenix head and body */}
<path d="M12 2 L13 4 L12 6 L11 4 Z" />

{/* Left wing */}
<path d="M11 6 Q8 8 6 12 Q5 14 4 16 L5 17 Q6 15 8 13 Q10 10 11 8 Z" />

{/* Right wing */}
<path d="M13 6 Q16 8 18 12 Q19 14 20 16 L19 17 Q18 15 16 13 Q14 10 13 8 Z" />

{/* Body center with gem */}
<ellipse cx="12" cy="10" rx="2" ry="3" fill="currentColor" opacity="0.3" />
<circle cx="12" cy="10" r="1" fill="currentColor" />

{/* Tail flames - left */}
<path d="M10 12 Q8 16 7 20 L8 21 Q9 18 10 14 Z" />

{/* Tail flames - center */}
<path d="M12 12 Q12 16 12 22" />

{/* Tail flames - right */}
<path d="M14 12 Q16 16 17 20 L16 21 Q15 18 14 14 Z" />

{/* Wing details - left */}
<path d="M9 9 L7 11" opacity="0.5" />
<path d="M8 11 L6 14" opacity="0.5" />

{/* Wing details - right */}
<path d="M15 9 L17 11" opacity="0.5" />
<path d="M16 11 L18 14" opacity="0.5" />

{/* Top flames */}
<path d="M11 4 Q10 2 9 1" opacity="0.6" />
<path d="M13 4 Q14 2 15 1" opacity="0.6" />
</svg>
);
};

51 changes: 31 additions & 20 deletions frontend/src/components/PlayerCard.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,45 @@
import { motion } from 'framer-motion';
import { Sparkles } from 'lucide-react';
import { XPBar } from './XPBar';
import { APBar } from './XPBar';

interface PlayerCardProps {
name: string;
picture: string;
level: number;
totalXP: number;
totalAP: number;
}

export const PlayerCard = ({ name, picture, level, totalXP }: PlayerCardProps) => {
export const PlayerCard = ({ name, picture, level, totalAP }: PlayerCardProps) => {
return (
<div className="glass glass-hover rounded-2xl p-8 relative overflow-hidden">
{/* Gradient Overlay */}
<div className="absolute inset-0 bg-gradient-to-br from-primary/10 to-secondary/10 -z-10" />

{/* Stylish Level Badge - Top Right */}
<motion.div
className="absolute top-6 right-6 flex items-center gap-3 px-5 py-3 rounded-2xl gradient-bg shadow-2xl"
initial={{ opacity: 0, scale: 0.8, x: 20 }}
animate={{ opacity: 1, scale: 1, x: 0 }}
whileHover={{ scale: 1.05 }}
transition={{ duration: 0.3 }}
style={{
boxShadow: '0 0 30px hsl(var(--glow-primary)), 0 10px 40px -10px hsl(var(--glow-secondary))',
}}
>
<motion.div
animate={{ rotate: 360 }}
transition={{ duration: 3, repeat: Infinity, ease: 'linear' }}
>
<Sparkles className="w-5 h-5 fill-white text-white" />
</motion.div>
<div className="flex flex-col items-center gap-0.5">
<span className="text-white/80 text-xs font-body uppercase tracking-wider">Level</span>
<span className="font-heading text-2xl font-black text-white leading-none">
{level}
</span>
</div>
</motion.div>

<div className="flex items-center gap-6 mb-6">
{/* Avatar with Glow */}
<motion.div
Expand All @@ -31,20 +56,6 @@ export const PlayerCard = ({ name, picture, level, totalXP }: PlayerCardProps) =
alt={name}
className="w-24 h-24 rounded-full border-2 border-white/30 relative z-10"
/>

{/* Level Badge */}
<motion.div
className="absolute -bottom-2 -right-2 w-12 h-12 rounded-full gradient-bg flex items-center justify-center shadow-lg z-20"
animate={{ rotate: 360 }}
transition={{ duration: 20, repeat: Infinity, ease: 'linear' }}
>
<div className="flex flex-col items-center">
<Sparkles className="w-3 h-3 fill-white text-white" />
<span className="font-heading text-xs font-bold text-white">
{level}
</span>
</div>
</motion.div>
</motion.div>

{/* Player Info */}
Expand All @@ -53,13 +64,13 @@ export const PlayerCard = ({ name, picture, level, totalXP }: PlayerCardProps) =
{name}
</h2>
<p className="text-muted-foreground font-body">
Level {level} Adventurer
Adventurer
</p>
</div>
</div>

{/* XP Bar */}
<XPBar totalXP={totalXP} />
{/* AP Bar */}
<APBar totalAP={totalAP} />
</div>
);
};
4 changes: 2 additions & 2 deletions frontend/src/components/QuestCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ export const QuestCard = ({ quest, onComplete }: QuestCardProps) => {
{quest.description}
</p>

{/* XP Badge */}
{/* AP Badge */}
<div className="flex items-center gap-2 bg-accent/20 rounded-xl px-3 py-2 w-fit">
<Zap className="w-4 h-4 fill-accent text-accent" />
<span className="font-heading font-bold text-accent">
{quest.xp} XP
{quest.xp} AP
</span>
</div>

Expand Down
18 changes: 9 additions & 9 deletions frontend/src/components/XPBar.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import { motion } from 'framer-motion';
import { getXPPercentage, getCurrentLevelXP } from '@/utils/questGenerator';
import { getAPPercentage, getCurrentLevelAP } from '@/utils/questGenerator';

interface XPBarProps {
totalXP: number;
interface APBarProps {
totalAP: number;
}

export const XPBar = ({ totalXP }: XPBarProps) => {
const percentage = getXPPercentage(totalXP);
const currentXP = getCurrentLevelXP(totalXP);
export const APBar = ({ totalAP }: APBarProps) => {
const percentage = getAPPercentage(totalAP);
const currentAP = getCurrentLevelAP(totalAP);

return (
<div className="w-full space-y-2">
<div className="flex justify-between items-center text-sm">
<span className="text-muted-foreground font-body">XP Progress</span>
<span className="text-muted-foreground font-body">AP Progress</span>
<span className="font-heading text-foreground">
{currentXP} / 100 XP
{currentAP} / 100 AP
</span>
</div>

<div className="relative h-8 bg-black/30 rounded-full border border-white/10 overflow-hidden">
{/* XP Fill */}
{/* AP Fill */}
<motion.div
className="absolute inset-y-0 left-0 gradient-bg shine-effect"
initial={{ width: 0 }}
Expand Down
18 changes: 9 additions & 9 deletions frontend/src/data/questTemplates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface QuestTemplate {
}

export const questTemplates: QuestTemplate[] = [
// STUDY - CASUAL (E rank, 10-25 XP)
// STUDY - CASUAL (E rank, 10-25 AP)
{
title: 'Review Notes',
description: 'Review your notes for 15 minutes',
Expand Down Expand Up @@ -52,7 +52,7 @@ export const questTemplates: QuestTemplate[] = [
difficulty: 'casual',
},

// STUDY - BALANCED (C rank, 50-100 XP)
// STUDY - BALANCED (C rank, 50-100 AP)
{
title: 'Deep Study Session',
description: 'Complete a focused 45-minute study session',
Expand Down Expand Up @@ -94,7 +94,7 @@ export const questTemplates: QuestTemplate[] = [
difficulty: 'balanced',
},

// STUDY - HARDCORE (A rank, 250-500 XP)
// STUDY - HARDCORE (A rank, 250-500 AP)
{
title: 'Master a Chapter',
description: 'Complete all exercises and notes for an entire chapter',
Expand Down Expand Up @@ -136,7 +136,7 @@ export const questTemplates: QuestTemplate[] = [
difficulty: 'hardcore',
},

// FITNESS - CASUAL (E rank, 10-25 XP)
// FITNESS - CASUAL (E rank, 10-25 AP)
{
title: 'Morning Stretch',
description: 'Complete a 10-minute stretching routine',
Expand Down Expand Up @@ -178,7 +178,7 @@ export const questTemplates: QuestTemplate[] = [
difficulty: 'casual',
},

// FITNESS - BALANCED (C rank, 50-100 XP)
// FITNESS - BALANCED (C rank, 50-100 AP)
{
title: 'Full Workout',
description: 'Complete a 30-minute workout session',
Expand Down Expand Up @@ -220,7 +220,7 @@ export const questTemplates: QuestTemplate[] = [
difficulty: 'balanced',
},

// FITNESS - HARDCORE (A rank, 250-500 XP)
// FITNESS - HARDCORE (A rank, 250-500 AP)
{
title: 'Intense Workout',
description: 'Complete a 60-minute high-intensity workout',
Expand Down Expand Up @@ -262,7 +262,7 @@ export const questTemplates: QuestTemplate[] = [
difficulty: 'hardcore',
},

// PRODUCTIVITY - CASUAL (E rank, 10-25 XP)
// PRODUCTIVITY - CASUAL (E rank, 10-25 AP)
{
title: 'Inbox Zero',
description: 'Clear your email inbox',
Expand Down Expand Up @@ -304,7 +304,7 @@ export const questTemplates: QuestTemplate[] = [
difficulty: 'casual',
},

// PRODUCTIVITY - BALANCED (C rank, 50-100 XP)
// PRODUCTIVITY - BALANCED (C rank, 50-100 AP)
{
title: 'Deep Work Session',
description: 'Complete 2 hours of focused deep work',
Expand Down Expand Up @@ -346,7 +346,7 @@ export const questTemplates: QuestTemplate[] = [
difficulty: 'balanced',
},

// PRODUCTIVITY - HARDCORE (A rank, 250-500 XP)
// PRODUCTIVITY - HARDCORE (A rank, 250-500 AP)
{
title: 'Major Milestone',
description: 'Complete a major project milestone',
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/pages/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default function Dashboard() {
setShowLevelUpModal(true);
}

toast.success('Quest completed! XP earned!');
toast.success('Quest completed! AP earned!');
};

const handleLogout = () => {
Expand All @@ -80,7 +80,7 @@ export default function Dashboard() {
toast.success('Logged out successfully');
};

const activeQuests = quests.filter((q) => q.status === 'active');
const activeQuests = quests.filter((q) => q.status === 'pending');
const completedQuests = quests.filter((q) => q.status === 'completed');

if (!user || !preferences) {
Expand All @@ -102,7 +102,7 @@ export default function Dashboard() {
},
{
icon: Zap,
label: 'Total XP',
label: 'Total AP',
value: totalXP,
color: '#06B6D4',
},
Expand Down Expand Up @@ -138,7 +138,7 @@ export default function Dashboard() {
name={user.name}
picture={user.picture}
level={level}
totalXP={totalXP}
totalAP={totalXP}
/>

{/* Generate Quests Button */}
Expand Down
Loading