bookwiz.io / app / dashboard / page.tsx
page.tsx
Raw
'use client'

import React from 'react'
import Link from 'next/link'
import Image from 'next/image'
import { useAuth } from '@/components/AuthProvider'
import { useUsageStats } from '@/lib/hooks/useUsageStats'
import { useProfile } from '@/lib/hooks/useProfile'
import { useBooks } from '@/lib/hooks/useBooks'
import { useWelcomeTour } from '@/lib/hooks/useWelcomeTour'
import DashboardLayout from '@/components/dashboard/DashboardLayout'
import UsageStatsGrid from '@/components/dashboard/UsageStatsGrid'
import UsageStatsSkeleton from '@/components/dashboard/UsageStatsSkeleton'
import RecentBooksSkeleton from '@/components/dashboard/RecentBooksSkeleton'
import WelcomeTour from '@/components/WelcomeTour'
import {
  BookOpenIcon,
  PlusIcon,
  ClockIcon,
  ArrowRightIcon,
  FireIcon,
  RocketLaunchIcon
} from '@heroicons/react/24/outline'

export default function DashboardPage() {
  const { user } = useAuth()
  const { profile, loading: profileLoading } = useProfile()
  const { usageStats, getSmartUsagePercentage, getFastUsagePercentage, loading: statsLoading } = useUsageStats()
  const { getRecentBooks, loading: booksLoading } = useBooks()
  const { isOpen: isTourOpen, closeTour, completeTour } = useWelcomeTour()
  
  const recentBooks = getRecentBooks(5)

  const formatDate = (dateString: string) => {
    return new Date(dateString).toLocaleDateString('en-US', {
      month: 'short',
      day: 'numeric',
      year: 'numeric'
    })
  }

  const getGreeting = () => {
    const hour = new Date().getHours()
    if (hour < 12) return 'Good morning'
    if (hour < 18) return 'Good afternoon'
    return 'Good evening'
  }

  const firstName = (profile?.full_name || user?.user_metadata?.full_name)?.split(' ')[0] || user?.email?.split('@')[0] || 'Writer'

  // Show skeleton title while profile is loading
  const getTitle = () => {
    if (profileLoading) {
      return (
        <div className="flex items-center space-x-2">
          <span>{getGreeting()}, </span>
          <div className="w-20 h-8 bg-white/20 rounded animate-pulse"></div>
          <span>๐Ÿ‘‹</span>
        </div>
      )
    }
    return `${getGreeting()}, ${firstName} ๐Ÿ‘‹`
  }

  return (
    <>
      <style jsx>{`
        @keyframes fadeIn {
          from {
            opacity: 0;
            transform: translateY(10px);
          }
          to {
            opacity: 1;
            transform: translateY(0);
          }
        }
      `}</style>
      
      <DashboardLayout 
        title={getTitle()}
        subtitle="Ready to create something amazing?"
      >
        {/* Stats Grid - Show skeleton while loading */}
        {statsLoading ? (
          <UsageStatsSkeleton />
        ) : (
          <UsageStatsGrid 
            usageStats={usageStats}
            getSmartUsagePercentage={getSmartUsagePercentage}
            getFastUsagePercentage={getFastUsagePercentage}
          />
        )}

        {/* Main Content Grid */}
        <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
          {/* Recent Books */}
          {booksLoading ? (
            <RecentBooksSkeleton />
          ) : (
            <div className="lg:col-span-2">
              <div className="flex flex-col space-y-2 sm:flex-row sm:items-center sm:justify-between sm:space-y-0 mb-4">
                <h2 className="text-lg sm:text-xl font-black text-white">Recent Books</h2>
                <Link 
                  href="/dashboard/books"
                  className="text-sm font-bold text-blue-400 hover:text-blue-300 transition-colors flex items-center space-x-1 self-start sm:self-auto"
                >
                  <span>View All</span>
                  <ArrowRightIcon className="w-4 h-4" />
                </Link>
              </div>
              
              {recentBooks.length > 0 ? (
                <div className="space-y-3">
                  {recentBooks.slice(0, 3).map((book) => (
                    <Link 
                      key={book.id} 
                      href={`/books/${book.id}`}
                      className="group block bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-4 hover:bg-white/10 transition-all duration-200"
                    >
                      <div className="flex items-center space-x-4">
                        {/* Book Cover */}
                        <div className="relative w-16 h-20 sm:w-20 sm:h-24 flex-shrink-0 overflow-hidden rounded-lg bg-gradient-to-br from-gray-800 to-gray-900">
                          <Image
                            src={book.cover_image_url || '/images/missingcover.webp'}
                            alt={`Cover for ${book.title}`}
                            fill
                            className="object-cover group-hover:scale-105 transition-transform duration-300"
                            sizes="(max-width: 640px) 64px, 80px"
                          />
                          {/* Book Spine Effect */}
                          <div className="absolute left-0 top-0 bottom-0 w-0.5 bg-gradient-to-b from-gray-700/50 to-gray-900/50"></div>
                        </div>
                        
                        {/* Book Info */}
                        <div className="flex-1 min-w-0">
                          <h3 className="text-white font-bold mb-1 group-hover:text-gray-200 truncate">
                            {book.title}
                          </h3>
                          {book.author && (
                            <p className="text-sm text-gray-400 mb-2 truncate">
                              by {book.author}
                            </p>
                          )}
                          <div className="flex flex-col space-y-1 sm:flex-row sm:items-center sm:space-y-0 sm:space-x-4 text-xs text-gray-400">
                            <span className="flex items-center space-x-1">
                              <span>{book.word_count.toLocaleString()} words</span>
                            </span>
                            <span className="flex items-center space-x-1">
                              <ClockIcon className="w-3 h-3 flex-shrink-0" />
                              <span>{formatDate(book.lastModified)}</span>
                            </span>
                          </div>
                        </div>
                        
                        {/* Arrow Icon */}
                        <ArrowRightIcon className="w-4 h-4 text-gray-500 group-hover:text-gray-300 group-hover:translate-x-1 transition-all flex-shrink-0" />
                      </div>
                    </Link>
                  ))}
                </div>
              ) : (
                <div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6 sm:p-8 text-center">
                  <RocketLaunchIcon className="h-10 w-10 sm:h-12 sm:w-12 text-gray-600 mx-auto mb-4" />
                  <h3 className="text-base sm:text-lg font-bold text-white mb-2">Start Your Writing Journey</h3>
                  <p className="text-sm sm:text-base text-gray-500 mb-6">Your first book awaits. Let&apos;s create something incredible.</p>
                  <Link 
                    href="/dashboard/books"
                    className="inline-flex items-center space-x-2 px-4 sm:px-6 py-2.5 sm:py-3 bg-gradient-to-r from-emerald-500 to-teal-600 hover:from-emerald-600 hover:to-teal-700 text-white font-bold rounded-2xl transition-all duration-200 text-sm sm:text-base"
                  >
                    <BookOpenIcon className="w-4 h-4" />
                    <span>Visit Books</span>
                  </Link>
                </div>
              )}
            </div>
          )}

          {/* Quick Actions - Always show (no loading needed) */}
          <div>
            <h2 className="text-lg sm:text-xl font-black text-white mb-4">Quick Actions</h2>
            <div className="space-y-3">
              <Link 
                href="/dashboard/books"
                className="group block bg-gradient-to-br from-blue-500/10 to-purple-500/10 border border-white/10 rounded-2xl p-4 hover:from-blue-500/20 hover:to-purple-500/20 transition-all duration-200"
              >
                <div className="flex items-center space-x-3 sm:space-x-4">
                  <div className="w-10 h-10 sm:w-12 sm:h-12 rounded-xl bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center flex-shrink-0">
                    <PlusIcon className="w-5 h-5 sm:w-6 sm:h-6 text-white" />
                  </div>
                  <div className="min-w-0">
                    <h3 className="text-white font-bold mb-1 text-sm sm:text-base">New Book</h3>
                    <p className="text-gray-400 text-xs sm:text-sm">Start writing</p>
                  </div>
                </div>
              </Link>

              <Link 
                href="/dashboard/billing"
                className="group block bg-gradient-to-br from-amber-500/10 to-orange-500/10 border border-white/10 rounded-2xl p-4 hover:from-amber-500/20 hover:to-orange-500/20 transition-all duration-200"
              >
                <div className="flex items-center space-x-3 sm:space-x-4">
                  <div className="w-10 h-10 sm:w-12 sm:h-12 rounded-xl bg-gradient-to-br from-amber-500 to-orange-600 flex items-center justify-center flex-shrink-0">
                    <FireIcon className="w-5 h-5 sm:w-6 sm:h-6 text-white" />
                  </div>
                  <div className="min-w-0">
                    <h3 className="text-white font-bold mb-1 text-sm sm:text-base">Upgrade</h3>
                    <p className="text-gray-400 text-xs sm:text-sm">Unlock AI power</p>
                  </div>
                </div>
              </Link>

              <Link 
                href="/dashboard/docs"
                className="group block bg-gradient-to-br from-emerald-500/10 to-teal-500/10 border border-white/10 rounded-2xl p-4 hover:from-emerald-500/20 hover:to-teal-500/20 transition-all duration-200"
              >
                <div className="flex items-center space-x-3 sm:space-x-4">
                  <div className="w-10 h-10 sm:w-12 sm:h-12 rounded-xl bg-gradient-to-br from-emerald-500 to-teal-600 flex items-center justify-center flex-shrink-0">
                    <BookOpenIcon className="w-5 h-5 sm:w-6 sm:h-6 text-white" />
                  </div>
                  <div className="min-w-0">
                    <h3 className="text-white font-bold mb-1 text-sm sm:text-base">Learn</h3>
                    <p className="text-gray-400 text-xs sm:text-sm">Master Bookwiz</p>
                  </div>
                </div>
              </Link>
            </div>
          </div>
        </div>

        {/* Welcome Tour */}
        <WelcomeTour 
          isOpen={isTourOpen}
          onClose={() => closeTour('skipped')}
          onComplete={completeTour}
        />
      </DashboardLayout>
    </>
  )
}