Skip to content

Commit d4ca3b2

Browse files
authored
Merge pull request #61 from chiscookeke11/issue-#54
Implement Two Reusable Analytics Pages
2 parents 2f55e0d + 60d6377 commit d4ca3b2

21 files changed

Lines changed: 7395 additions & 6107 deletions

app/Analytics-Details/page.tsx

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import AnalyticsChart from "@/components/analytics/AnalyticsChart";
2+
import UserNav from "@/components/analytics/UserNav";
3+
import UserStats from "@/components/analytics/UserStats";
4+
import { SocialLinks } from "@/utils/interface";
5+
import { BsDiscord, BsGlobe, BsTelegram, BsTwitterX } from "react-icons/bs";
6+
7+
8+
9+
10+
11+
export default function Page() {
12+
13+
14+
const projectTags: string[] = ["DAO", "NFT", "NFT marketplace"]
15+
16+
const projectDescription: string = "Need a marketplace for your infrastructure? This is the perfect..."
17+
18+
const socialLinks: SocialLinks[] = [
19+
{
20+
link: "",
21+
icon: <BsGlobe size={20} />,
22+
},
23+
{
24+
link: "",
25+
icon: <BsDiscord size={20} />,
26+
},
27+
{
28+
link: "",
29+
icon: <BsTelegram size={20} />,
30+
},
31+
{
32+
link: "",
33+
icon: <BsTwitterX size={20} />
34+
}
35+
]
36+
37+
38+
39+
return (
40+
<div className="bg-[#111111] pb-10 font-satoshi " >
41+
<UserNav />
42+
<UserStats
43+
projectTags={projectTags}
44+
projectDescription={projectDescription}
45+
socialLinks={socialLinks}
46+
/>
47+
48+
49+
<section className="w-full max-w-[1400px] mx-auto mt-[50px] px-4 md:px-0 ">
50+
{/* Nav buttons */}
51+
<div className="w-full flex items-center gap-10 border-b-[2px] border-[#988C8C4F] pb-2">
52+
<button
53+
className={`text-xl font-normal relative
54+
text-[#988C8C]
55+
before:content-['']
56+
before:absolute
57+
before:bottom-[-8px]
58+
before:bg-[#E0FFB0]
59+
before:h-[3px]
60+
hover:before:w-full
61+
before:transition-all
62+
before:duration-200
63+
before:ease-in-out
64+
before:w-0}
65+
`}
66+
>
67+
Home
68+
</button>
69+
70+
<button
71+
className={`text-xl font-normal relative
72+
text-[#988C8C]
73+
before:content-['']
74+
before:absolute
75+
before:bottom-[-8px]
76+
before:bg-[#E0FFB0]
77+
before:h-[3px]
78+
hover:before:w-full
79+
before:transition-all
80+
before:duration-200
81+
before:ease-in-out before:w-0
82+
`}
83+
>
84+
Analytics
85+
</button>
86+
</div>
87+
88+
{/* Section content */}
89+
90+
<div className=" w-full rounded-lg border-[#988C8C] border-[1px] mx-auto mt-[30px] h-[179px] bg-[url('/item-image.svg')] bg-no-repeat bg-center bg-cover flex items-center px-[3%] " >
91+
92+
<h1 className="font-bold text-2xl md:text-[32px] text-[#ffffff] " >DAO Voter</h1>
93+
94+
</div>
95+
96+
97+
<div className="w-full flex flex-col md:flex-row gap-10 justify-between items-start mt-[70px] " >
98+
99+
100+
<div className="w-full md:max-w-[190px] flex-col items-center md:items-start gap-5 " >
101+
<div className="flex flex-col items-center md:items-start gap-8 ">
102+
<h2 className="text-[#FFFFFF] text-2xl md:text-[32px] font-medium " >Participants</h2>
103+
<div className="flex items-center gap-4" >
104+
<div className="w-[85px] h-[85px] flex flex-col items-start justify-center gap-2 " >
105+
<p className=" font-normal text-lg text-[#EBFFCB] " >Active</p>
106+
<span className="border-[1px] border-[#988C8C] rounded-[10px] w-[55px] h-[55px] md:w-[85px] md:h-[50px] text-base md:text-[28px] font-medium text-[#EBFFCB] flex items-center justify-center " >543</span>
107+
108+
</div>
109+
110+
111+
<div className="w-[85px] h-[85px] flex flex-col items-center justify-center gap-2 " >
112+
<p className=" font-normal text-lg text-[#988C8C] " >Inactive</p>
113+
<span className=" rounded-[10px] w-[55px] h-[55px] md:w-[85px] md:h-[50px] text-base md:text-[28px] font-medium text-[#988C8C] flex items-center justify-center " >543</span>
114+
115+
</div>
116+
</div>
117+
118+
</div>
119+
<p className="text-[#E0FFB0] font-normal text-2xl mt-[14px] text-center md:text-left " >May 20 - May 31</p>
120+
</div>
121+
122+
123+
124+
<div className="w-full max-w-[868px] " >
125+
126+
<AnalyticsChart/>
127+
</div>
128+
129+
</div>
130+
131+
132+
133+
134+
135+
</section>
136+
137+
138+
139+
</div>
140+
)
141+
}

app/analytics-overview/page.tsx

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import AnalyticsSection from "@/components/analytics/AnalyticsSection";
2+
import { cardData } from "@/components/analytics/data";
3+
import UserNav from "@/components/analytics/UserNav";
4+
import UserStats from "@/components/analytics/UserStats";
5+
import { SocialLinks } from "@/utils/interface";
6+
import { BsDiscord, BsGlobe, BsTelegram, BsTwitterX } from "react-icons/bs";
7+
8+
9+
10+
11+
12+
13+
14+
export default function Page() {
15+
16+
17+
const projectTags: string[] = ["DAO", "NFT", "NFT marketplace"]
18+
19+
const projectDescription: string = "Need a marketplace for your infrastructure? This is the perfect..."
20+
21+
const socialLinks: SocialLinks[] = [
22+
{
23+
link: "",
24+
icon: <BsGlobe size={20} />,
25+
},
26+
{
27+
link: "",
28+
icon: <BsDiscord size={20} />,
29+
},
30+
{
31+
link: "",
32+
icon: <BsTelegram size={20} />,
33+
},
34+
{
35+
link: "",
36+
icon: <BsTwitterX size={20} />
37+
}
38+
]
39+
40+
41+
42+
43+
44+
45+
46+
47+
48+
return (
49+
<div className="bg-[#111111] pb-5 font-satoshi " >
50+
<UserNav />
51+
<UserStats
52+
projectTags={projectTags}
53+
projectDescription={projectDescription}
54+
socialLinks={socialLinks}
55+
/>
56+
<AnalyticsSection data={cardData} />
57+
</div>
58+
)
59+
}

app/page.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { redirect } from "next/navigation";
2-
3-
export default function Home() {
4-
redirect("/onboard");
5-
}
1+
import { redirect } from "next/navigation";
2+
3+
export default function Home() {
4+
redirect("/onboard");
5+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
"use client"
2+
3+
import { useState } from "react"
4+
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts"
5+
6+
const weeklyData = [
7+
{ day: "Sun", users: 150, date: "May 19" },
8+
{ day: "Mon", users: 780, date: "May 20" },
9+
{ day: "Tue", users: 420, date: "May 21" },
10+
{ day: "Wed", users: 950, date: "May 22" },
11+
{ day: "Thu", users: 600, date: "May 23" },
12+
{ day: "Fri", users: 725, date: "May 24" },
13+
{ day: "Sat", users: 580, date: "May 25" },
14+
]
15+
16+
const monthlyData = [
17+
{ day: "Week 1", users: 450, date: "May 1-7" },
18+
{ day: "Week 2", users: 680, date: "May 8-14" },
19+
{ day: "Week 3", users: 820, date: "May 15-21" },
20+
{ day: "Week 4", users: 720, date: "May 22-28" },
21+
]
22+
23+
const CustomTooltip = ({ active, payload, label }: any) => {
24+
if (active && payload && payload.length) {
25+
const data = payload[0].payload
26+
return (
27+
<div className="bg-gray-800 border border-gray-600 rounded-lg p-3 shadow-lg">
28+
<div className="text-gray-300 text-sm font-medium mb-1">{data.date}</div>
29+
<div className="text-white text-lg font-semibold">{payload[0].value} users</div>
30+
</div>
31+
)
32+
}
33+
return null
34+
}
35+
36+
export default function AnalyticsChart() {
37+
const [timeframe, setTimeframe] = useState("weekly")
38+
const data = timeframe === "weekly" ? weeklyData : monthlyData
39+
40+
return (
41+
<div className="w-full h-fit p-3 md:p-6">
42+
<div className="flex justify-end mb-6">
43+
<select
44+
value={timeframe}
45+
onChange={(e) => setTimeframe(e.target.value)}
46+
className="bg-transparent border border-gray-600 text-white rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
47+
>
48+
<option value="weekly" className="bg-gray-800 text-white">
49+
Weekly
50+
</option>
51+
<option value="monthly" className="bg-gray-800 text-white">
52+
Monthly
53+
</option>
54+
</select>
55+
</div>
56+
57+
<div className="h-96">
58+
<ResponsiveContainer width="100%" height="100%">
59+
<AreaChart
60+
data={data}
61+
margin={{
62+
top: 20,
63+
bottom: 20,
64+
}}
65+
>
66+
<defs>
67+
<linearGradient id="userGradient" x1="0" y1="0" x2="0" y2="1">
68+
<stop offset="0%" stopColor="#22c55e" stopOpacity={0.8} />
69+
<stop offset="100%" stopColor="#22c55e" stopOpacity={0.1} />
70+
</linearGradient>
71+
</defs>
72+
<CartesianGrid strokeDasharray="3 3" stroke="#374151" strokeOpacity={0.3} />
73+
<XAxis dataKey="day" axisLine={false} tickLine={false} tick={{ fill: "#9CA3AF", fontSize: 12 }} />
74+
<YAxis
75+
axisLine={false}
76+
tickLine={false}
77+
tick={{ fill: "#9CA3AF", fontSize: 12 }}
78+
domain={[0, 1000]}
79+
ticks={[200, 400, 600, 800, 1000]}
80+
/>
81+
<Tooltip content={<CustomTooltip />} />
82+
<Area
83+
type="monotone"
84+
dataKey="users"
85+
stroke="#22c55e"
86+
strokeWidth={3}
87+
fill="url(#userGradient)"
88+
dot={{ fill: "#22c55e", strokeWidth: 2, r: 4 }}
89+
activeDot={{ r: 6, fill: "#22c55e", strokeWidth: 2, stroke: "#000" }}
90+
/>
91+
</AreaChart>
92+
</ResponsiveContainer>
93+
</div>
94+
</div>
95+
)
96+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { CardProps } from "@/utils/interface";
2+
import ItemCard from "./ItemCard";
3+
4+
5+
interface AnalyticsDisplayProps{
6+
data: CardProps[]
7+
}
8+
9+
export default function AnalyticsDisplay({data}: AnalyticsDisplayProps) {
10+
return (
11+
<div className=" grid grid-cols-1 md:grid-cols-2 gap-7 min-h-[30vh] place-items-center " >
12+
{data.map((card, index) => (
13+
<ItemCard key={index} data={card} />
14+
))}
15+
16+
</div>
17+
)
18+
}

0 commit comments

Comments
 (0)