diff --git a/app/src/app/globals.css b/app/src/app/globals.css
index 23d132e..9f89ffc 100644
--- a/app/src/app/globals.css
+++ b/app/src/app/globals.css
@@ -1,75 +1,77 @@
@import "tailwindcss";
-:root {
- --background: #000000;
- --foreground: #ffffff;
-}
-
-@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
-}
-
-body {
- background: var(--background);
- color: var(--foreground);
- font-family: Arial, Helvetica, sans-serif;
- margin: 0;
- padding: 0;
-}
-
-/* Custom scrollbar for dark theme */
-::-webkit-scrollbar {
- width: 8px;
- height: 8px;
-}
-
-::-webkit-scrollbar-track {
- background: #000000;
-}
-
-::-webkit-scrollbar-thumb {
- background: #374151;
- border-radius: 4px;
-}
-
-::-webkit-scrollbar-thumb:hover {
- background: #4B5563;
-}
-
-/* Hide scrollbar for album container */
-.scrollbar-hide {
- -ms-overflow-style: none; /* IE and Edge */
- scrollbar-width: none; /* Firefox */
-}
-
-.scrollbar-hide::-webkit-scrollbar {
- display: none; /* Chrome, Safari and Opera */
-}
-
-@layer utilities {
- @keyframes music {
- 0%, 100% {
- height: 20%;
- }
- 50% {
- height: 100%;
- }
- }
-
- .animate-music {
- animation: music 1s ease-in-out infinite;
- }
-}
-
-@layer utilities {
- .animate-music-fast {
- animation: music 0.6s ease-in-out infinite;
- }
-
- .animate-music-slow {
- animation: music 1.4s ease-in-out infinite;
- }
-}
+@custom-variant dark (&:where(.dark, .dark *));
+
+:root {
+ --background: #000000;
+ --foreground: #ffffff;
+}
+
+@theme inline {
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --font-sans: var(--font-geist-sans);
+ --font-mono: var(--font-geist-mono);
+}
+
+body {
+ background: var(--background);
+ color: var(--foreground);
+ font-family: Arial, Helvetica, sans-serif;
+ margin: 0;
+ padding: 0;
+}
+
+/* Custom scrollbar for dark theme */
+::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+}
+
+::-webkit-scrollbar-track {
+ background: #000000;
+}
+
+::-webkit-scrollbar-thumb {
+ background: #374151;
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: #4B5563;
+}
+
+/* Hide scrollbar for album container */
+.scrollbar-hide {
+ -ms-overflow-style: none; /* IE and Edge */
+ scrollbar-width: none; /* Firefox */
+}
+
+.scrollbar-hide::-webkit-scrollbar {
+ display: none; /* Chrome, Safari and Opera */
+}
+
+@layer utilities {
+ @keyframes music {
+ 0%, 100% {
+ height: 20%;
+ }
+ 50% {
+ height: 100%;
+ }
+ }
+
+ .animate-music {
+ animation: music 1s ease-in-out infinite;
+ }
+}
+
+@layer utilities {
+ .animate-music-fast {
+ animation: music 0.6s ease-in-out infinite;
+ }
+
+ .animate-music-slow {
+ animation: music 1.4s ease-in-out infinite;
+ }
+}
diff --git a/app/src/components/OverviewCards.tsx b/app/src/components/OverviewCards.tsx
index fefa7b7..97d5276 100644
--- a/app/src/components/OverviewCards.tsx
+++ b/app/src/components/OverviewCards.tsx
@@ -1,98 +1,98 @@
-'use client';
-
-import { featureFlags } from '@/lib/featureFlags';
-import { MOCK_OVERVIEW_CARDS } from '@/lib/mockData';
-import MockDataBadge from '@/components/MockDataBadge';
-import useOverviewServices from '@/services/overviewService';
-
-interface KpiCard {
- title: string;
- value: string;
- isFirst: boolean;
-}
-
-function formatCurrency(n: number): string {
- return `$${n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
-}
-
-function kpiToCards(data: { songsPublished: number; totalEarnings: number; listenersCount: number; mostStreamedRegion: string }): KpiCard[] {
- return [
- { title: 'Songs Published', value: String(data.songsPublished), isFirst: true },
- { title: 'Total Earnings', value: formatCurrency(data.totalEarnings), isFirst: false },
- { title: 'Listeners Count', value: data.listenersCount.toLocaleString('en-US'), isFirst: false },
- { title: 'Most Streamed Region', value: data.mostStreamedRegion, isFirst: false },
- ];
-}
-
-function CardGrid({ cards, isMock }: { cards: KpiCard[]; isMock: boolean }) {
- return (
-
-
- Overview
- {isMock && }
-
-
- {cards.map((card, index) => (
-
- {card.isFirst ? (
-
-
-
-
{card.title}
-
{card.value}
-
-
-
- ) : (
-
-
{card.title}
-
{card.value}
-
- )}
-
- ))}
-
-
- );
-}
-
-function OverviewCardsSkeleton() {
- return (
-
-
Overview
-
- {Array.from({ length: 4 }).map((_, i) => (
-
- ))}
-
-
- );
-}
-
-function LiveOverviewCards() {
- const { useGetOverviewKpi } = useOverviewServices();
- const { data, isLoading, isError } = useGetOverviewKpi();
-
- if (isLoading) return ;
-
- if (isError || !data?.data) {
- return (
-
-
Overview
-
Failed to load overview data. Please try again later.
-
- );
- }
-
- return ;
-}
-
-export default function OverviewCards() {
- if (featureFlags.useMockOverviewCards) {
- return ;
- }
- return ;
-}
+'use client';
+
+import { featureFlags } from '@/lib/featureFlags';
+import { MOCK_OVERVIEW_CARDS } from '@/lib/mockData';
+import MockDataBadge from '@/components/MockDataBadge';
+import useOverviewServices from '@/services/overviewService';
+
+interface KpiCard {
+ title: string;
+ value: string;
+ isFirst: boolean;
+}
+
+function formatCurrency(n: number): string {
+ return `$${n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
+}
+
+function kpiToCards(data: { songsPublished: number; totalEarnings: number; listenersCount: number; mostStreamedRegion: string }): KpiCard[] {
+ return [
+ { title: 'Songs Published', value: String(data.songsPublished), isFirst: true },
+ { title: 'Total Earnings', value: formatCurrency(data.totalEarnings), isFirst: false },
+ { title: 'Listeners Count', value: data.listenersCount.toLocaleString('en-US'), isFirst: false },
+ { title: 'Most Streamed Region', value: data.mostStreamedRegion, isFirst: false },
+ ];
+}
+
+function CardGrid({ cards, isMock }: { cards: KpiCard[]; isMock: boolean }) {
+ return (
+
+
+ Overview
+ {isMock && }
+
+
+ {cards.map((card, index) => (
+
+ {card.isFirst ? (
+
+
+
+
{card.title}
+
{card.value}
+
+
+
+ ) : (
+
+
{card.title}
+
{card.value}
+
+ )}
+
+ ))}
+
+
+ );
+}
+
+function OverviewCardsSkeleton() {
+ return (
+
+
Overview
+
+ {Array.from({ length: 4 }).map((_, i) => (
+
+ ))}
+
+
+ );
+}
+
+function LiveOverviewCards() {
+ const { useGetOverviewKpi } = useOverviewServices();
+ const { data, isLoading, isError } = useGetOverviewKpi();
+
+ if (isLoading) return ;
+
+ if (isError || !data?.data) {
+ return (
+
+
Overview
+
Failed to load overview data. Please try again later.
+
+ );
+ }
+
+ return ;
+}
+
+export default function OverviewCards() {
+ if (featureFlags.useMockOverviewCards) {
+ return ;
+ }
+ return ;
+}
diff --git a/app/src/components/Sidebar.tsx b/app/src/components/Sidebar.tsx
index 9c1a73a..bfcd91c 100644
--- a/app/src/components/Sidebar.tsx
+++ b/app/src/components/Sidebar.tsx
@@ -1,141 +1,141 @@
-'use client';
-
-import { Music, Calendar, Tag, Star, Home, X } from 'lucide-react';
-import Link from 'next/link';
-import Image from 'next/image';
-import { usePathname } from 'next/navigation';
-import { useEffect } from 'react';
-
-const navItems = [
- { name: 'Overview', icon: Home, href: '/dashboard/overview' },
- { name: 'My Music', icon: Music, href: '/dashboard/my-music' },
- { name: 'Events', icon: Calendar, href: '/dashboard/events' },
- { name: 'Merches', icon: Tag, href: '/dashboard/merches' },
- { name: 'Premium', icon: Star, href: '/dashboard/premium' },
-];
-
-const legalLinks = [
- { name: 'Privacy Center', href: '/privacy-center' },
- { name: 'Privacy Policy', href: '/privacy-policy' },
- { name: 'Cookies', href: '/cookies' },
-];
-
-export default function Sidebar({
- open,
- onClose,
-}: {
- open: boolean;
- onClose: () => void;
-}) {
- const pathname = usePathname();
-
- // Prevent body scroll while mobile drawer is open
- useEffect(() => {
- if (open) {
- document.body.style.overflow = 'hidden';
- } else {
- document.body.style.overflow = '';
- }
- return () => { document.body.style.overflow = ''; };
- }, [open]);
-
- return (
- <>
- {/* Mobile Dark Overlay */}
- {open && (
-
- )}
-
- {/* Sidebar */}
-
- {/* Mobile Header */}
-
-
-
-
-
- {/* Desktop Logo */}
-
-
-
-
-
-
- {/* Navigation */}
-
-
- {/* Legal */}
-
-
- Legal
-
- {legalLinks.map((link) => (
-
- {link.name}
-
- ))}
-
-
- >
- );
-}
\ No newline at end of file
+'use client';
+
+import { Music, Calendar, Tag, Star, Home, X } from 'lucide-react';
+import Link from 'next/link';
+import Image from 'next/image';
+import { usePathname } from 'next/navigation';
+import { useEffect } from 'react';
+
+const navItems = [
+ { name: 'Overview', icon: Home, href: '/dashboard/overview' },
+ { name: 'My Music', icon: Music, href: '/dashboard/my-music' },
+ { name: 'Events', icon: Calendar, href: '/dashboard/events' },
+ { name: 'Merches', icon: Tag, href: '/dashboard/merches' },
+ { name: 'Premium', icon: Star, href: '/dashboard/premium' },
+];
+
+const legalLinks = [
+ { name: 'Privacy Center', href: '/privacy-center' },
+ { name: 'Privacy Policy', href: '/privacy-policy' },
+ { name: 'Cookies', href: '/cookies' },
+];
+
+export default function Sidebar({
+ open,
+ onClose,
+}: {
+ open: boolean;
+ onClose: () => void;
+}) {
+ const pathname = usePathname();
+
+ // Prevent body scroll while mobile drawer is open
+ useEffect(() => {
+ if (open) {
+ document.body.style.overflow = 'hidden';
+ } else {
+ document.body.style.overflow = '';
+ }
+ return () => { document.body.style.overflow = ''; };
+ }, [open]);
+
+ return (
+ <>
+ {/* Mobile Dark Overlay */}
+ {open && (
+
+ )}
+
+ {/* Sidebar */}
+
+ {/* Mobile Header */}
+
+
+
+
+
+ {/* Desktop Logo */}
+
+
+
+
+
+
+ {/* Navigation */}
+
+
+ {/* Legal */}
+
+
+ Legal
+
+ {legalLinks.map((link) => (
+
+ {link.name}
+
+ ))}
+
+
+ >
+ );
+}
diff --git a/app/src/components/TopHeader.tsx b/app/src/components/TopHeader.tsx
index 72c9249..182a5a4 100644
--- a/app/src/components/TopHeader.tsx
+++ b/app/src/components/TopHeader.tsx
@@ -1,136 +1,136 @@
-'use client';
-
-import { Search, Bell, Menu } from 'lucide-react';
-import { useEffect, useState } from 'react';
-import Link from 'next/link';
-
-export default function TopHeader({
- onMenuClick,
- sidebarOpen = false,
-}: {
- onMenuClick: () => void;
- sidebarOpen?: boolean;
-}) {
- const [currentDate, setCurrentDate] = useState('');
- const [currentTime, setCurrentTime] = useState('');
-
- useEffect(() => {
- const updateDateTime = () => {
- const now = new Date();
-
- setCurrentDate(
- now.toLocaleDateString('en-GB', {
- day: 'numeric',
- month: 'long',
- year: 'numeric',
- })
- );
-
- setCurrentTime(
- now.toLocaleTimeString('en-GB', {
- hour: '2-digit',
- minute: '2-digit',
- hour12: true,
- timeZoneName: 'short',
- })
- );
- };
-
- updateDateTime();
- const interval = setInterval(updateDateTime, 60000);
- return () => clearInterval(interval);
- }, []);
-
- return (
-
- );
-}
+'use client';
+
+import { Search, Bell, Menu } from 'lucide-react';
+import { useEffect, useState } from 'react';
+import Link from 'next/link';
+
+export default function TopHeader({
+ onMenuClick,
+ sidebarOpen = false,
+}: {
+ onMenuClick: () => void;
+ sidebarOpen?: boolean;
+}) {
+ const [currentDate, setCurrentDate] = useState('');
+ const [currentTime, setCurrentTime] = useState('');
+
+ useEffect(() => {
+ const updateDateTime = () => {
+ const now = new Date();
+
+ setCurrentDate(
+ now.toLocaleDateString('en-GB', {
+ day: 'numeric',
+ month: 'long',
+ year: 'numeric',
+ })
+ );
+
+ setCurrentTime(
+ now.toLocaleTimeString('en-GB', {
+ hour: '2-digit',
+ minute: '2-digit',
+ hour12: true,
+ timeZoneName: 'short',
+ })
+ );
+ };
+
+ updateDateTime();
+ const interval = setInterval(updateDateTime, 60000);
+ return () => clearInterval(interval);
+ }, []);
+
+ return (
+
+ );
+}