|
1 | | -import Image from "next/image"; |
| 1 | +"use client"; |
| 2 | + |
| 3 | +import { useState } from "react"; |
| 4 | +import { Navigation } from "@/components/ui/Navigation"; |
| 5 | +import { FileUpload } from "@/components/ui/FileUpload"; |
| 6 | +import { BillingChart } from "@/components/charts/BillingChart"; |
| 7 | +import { GitHubBillingReport, BillingData } from "@/types/billing"; |
| 8 | + |
| 9 | +const sampleBillingData: BillingData[] = [ |
| 10 | + { month: "Jan", actions: 120, packages: 80, storage: 40 }, |
| 11 | + { month: "Feb", actions: 150, packages: 90, storage: 45 }, |
| 12 | + { month: "Mar", actions: 180, packages: 110, storage: 50 }, |
| 13 | + { month: "Apr", actions: 220, packages: 130, storage: 55 }, |
| 14 | + { month: "May", actions: 190, packages: 120, storage: 48 }, |
| 15 | + { month: "Jun", actions: 250, packages: 140, storage: 60 }, |
| 16 | +]; |
2 | 17 |
|
3 | 18 | export default function Home() { |
| 19 | + const [billingData, setBillingData] = |
| 20 | + useState<BillingData[]>(sampleBillingData); |
| 21 | + const [hasUploadedData, setHasUploadedData] = useState(false); |
| 22 | + |
| 23 | + const handleDataLoaded = (report: GitHubBillingReport) => { |
| 24 | + setBillingData(report.data); |
| 25 | + setHasUploadedData(true); |
| 26 | + }; |
| 27 | + |
4 | 28 | return ( |
5 | | - <div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20"> |
6 | | - <main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start"> |
7 | | - <Image |
8 | | - className="dark:invert" |
9 | | - src="/next.svg" |
10 | | - alt="Next.js logo" |
11 | | - width={180} |
12 | | - height={38} |
13 | | - priority |
14 | | - /> |
15 | | - <ol className="font-mono list-inside list-decimal text-sm/6 text-center sm:text-left"> |
16 | | - <li className="mb-2 tracking-[-.01em]"> |
17 | | - Get started by editing{" "} |
18 | | - <code className="bg-black/[.05] dark:bg-white/[.06] font-mono font-semibold px-1 py-0.5 rounded"> |
19 | | - src/app/page.tsx |
20 | | - </code> |
21 | | - . |
22 | | - </li> |
23 | | - <li className="tracking-[-.01em]"> |
24 | | - Save and see your changes instantly. |
25 | | - </li> |
26 | | - </ol> |
| 29 | + <div className="min-h-screen bg-gray-950 text-white"> |
| 30 | + <Navigation /> |
| 31 | + |
| 32 | + {/* Main Content */} |
| 33 | + <section className="relative py-32 px-4 sm:px-6 lg:px-8"> |
| 34 | + <div className="max-w-4xl mx-auto text-center"> |
| 35 | + <h1 className="text-5xl md:text-7xl font-bold mb-8 bg-gradient-to-r from-white to-gray-400 bg-clip-text text-transparent"> |
| 36 | + Understand Your |
| 37 | + <br /> |
| 38 | + <span className="bg-gradient-to-r from-green-400 to-blue-400 bg-clip-text text-transparent"> |
| 39 | + GitHub Costs |
| 40 | + </span> |
| 41 | + </h1> |
| 42 | + |
| 43 | + <p className="text-xl text-gray-400 mb-12 max-w-2xl mx-auto leading-relaxed"> |
| 44 | + Upload your GitHub billing report to visualize spending patterns and |
| 45 | + optimize costs. |
| 46 | + <br /> |
| 47 | + <span className="text-sm text-gray-500 mt-2 block"> |
| 48 | + Your data is processed locally and not stored on our servers. |
| 49 | + </span> |
| 50 | + </p> |
| 51 | + |
| 52 | + {/* File Upload */} |
| 53 | + <div className="mb-16"> |
| 54 | + <FileUpload onDataLoaded={handleDataLoaded} /> |
| 55 | + </div> |
| 56 | + |
| 57 | + {/* Chart Visualization */} |
| 58 | + <div className="max-w-6xl mx-auto"> |
| 59 | + <div className="bg-gray-800/50 backdrop-blur-sm border border-gray-700 rounded-xl p-8"> |
| 60 | + <BillingChart |
| 61 | + data={billingData} |
| 62 | + title={ |
| 63 | + hasUploadedData |
| 64 | + ? "Your GitHub Billing Data" |
| 65 | + : "Sample GitHub Billing Visualization" |
| 66 | + } |
| 67 | + /> |
| 68 | + </div> |
| 69 | + </div> |
| 70 | + </div> |
27 | 71 |
|
28 | | - <div className="flex gap-4 items-center flex-col sm:flex-row"> |
29 | | - <a |
30 | | - className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto" |
31 | | - href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" |
32 | | - target="_blank" |
33 | | - rel="noopener noreferrer" |
34 | | - > |
35 | | - <Image |
36 | | - className="dark:invert" |
37 | | - src="/vercel.svg" |
38 | | - alt="Vercel logomark" |
39 | | - width={20} |
40 | | - height={20} |
41 | | - /> |
42 | | - Deploy now |
43 | | - </a> |
44 | | - <a |
45 | | - className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]" |
46 | | - href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" |
47 | | - target="_blank" |
48 | | - rel="noopener noreferrer" |
49 | | - > |
50 | | - Read our docs |
51 | | - </a> |
| 72 | + {/* Background decoration */} |
| 73 | + <div className="absolute inset-0 -z-10"> |
| 74 | + <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-96 h-96 bg-green-500/10 rounded-full blur-3xl"></div> |
| 75 | + <div className="absolute top-1/4 right-1/4 w-64 h-64 bg-blue-500/10 rounded-full blur-3xl"></div> |
52 | 76 | </div> |
53 | | - </main> |
54 | | - <footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center"> |
55 | | - <a |
56 | | - className="flex items-center gap-2 hover:underline hover:underline-offset-4" |
57 | | - href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" |
58 | | - target="_blank" |
59 | | - rel="noopener noreferrer" |
60 | | - > |
61 | | - <Image |
62 | | - aria-hidden |
63 | | - src="/file.svg" |
64 | | - alt="File icon" |
65 | | - width={16} |
66 | | - height={16} |
67 | | - /> |
68 | | - Learn |
69 | | - </a> |
70 | | - <a |
71 | | - className="flex items-center gap-2 hover:underline hover:underline-offset-4" |
72 | | - href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" |
73 | | - target="_blank" |
74 | | - rel="noopener noreferrer" |
75 | | - > |
76 | | - <Image |
77 | | - aria-hidden |
78 | | - src="/window.svg" |
79 | | - alt="Window icon" |
80 | | - width={16} |
81 | | - height={16} |
82 | | - /> |
83 | | - Examples |
84 | | - </a> |
85 | | - <a |
86 | | - className="flex items-center gap-2 hover:underline hover:underline-offset-4" |
87 | | - href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" |
88 | | - target="_blank" |
89 | | - rel="noopener noreferrer" |
90 | | - > |
91 | | - <Image |
92 | | - aria-hidden |
93 | | - src="/globe.svg" |
94 | | - alt="Globe icon" |
95 | | - width={16} |
96 | | - height={16} |
97 | | - /> |
98 | | - Go to nextjs.org → |
99 | | - </a> |
100 | | - </footer> |
| 77 | + </section> |
101 | 78 | </div> |
102 | 79 | ); |
103 | 80 | } |
0 commit comments