Skip to content

Commit e5318c8

Browse files
committed
Some of gold
1 parent 7fddb2f commit e5318c8

File tree

21 files changed

+354
-148
lines changed

21 files changed

+354
-148
lines changed

app/api/profile-image/route.js

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,24 @@ const calculateUserXp = (xp) => Math.floor(xp / 1000);
77
// XP required to reach level L (linear): 1000 * L
88
const xpForLevel = (lvl) => 1000 * lvl;
99
const formatNumber = (num) => {
10-
if (num >= 1000000000) return (num / 1000000000).toFixed(1) + "B";
11-
if (num >= 1000000) return (num / 1000000).toFixed(1) + "M";
12-
if (num >= 1000) return (num / 1000).toFixed(1) + "k";
10+
if (num >= 1_000_000_000) return Math.floor(num / 100_000_000) / 10 + "B";
11+
if (num >= 1_000_000) return Math.floor(num / 100_000) / 10 + "M";
12+
if (num >= 1_000) return Math.floor(num / 100) / 10 + "k";
1313
return num.toString();
1414
};
1515

16+
1617
// 🎭 FAKE DATA - للعرض التجريبي فقط
1718
const FAKE_USER_DATA = {
18-
displayName: "マゼン",
19+
displayName: "mazinx",
1920
username: "mz_n",
2021
xp: 45750,
2122
credits: 1250000,
2223
reputation: 99,
2324
about:
2425
"Professional gamer and anime lover 🎮✨ | Building the best Discord community | Coffee addict ☕",
25-
rank: 127,
26-
avatar: "https://cdn.discordapp.com/avatars/618078478755037185/4336843200bf2537f6cd773e3ddd6bd2.png?size=1024",
26+
rank: 1,
27+
avatar: "https://cdn.discordapp.com/avatars/618078478755037185/6eb3714acb606504d5d1e63bc98c368a.png?size=1024",
2728
};
2829

2930
export async function GET() {
@@ -32,8 +33,8 @@ export async function GET() {
3233
const user = FAKE_USER_DATA;
3334

3435
const level = calculateUserXp(user.xp);
35-
const currentXP = user.xp - xpForLevel(level);
36-
const totalXP = xpForLevel(level + 1) - xpForLevel(level);
36+
const currentXP = user.xp ;
37+
const totalXP = xpForLevel(level + 1);
3738

3839
// Create canvas with custom profile dimensions
3940
const canvas = createCanvas(549, 548);
@@ -220,9 +221,7 @@ export async function GET() {
220221

221222
// Draw text with stroke
222223
ctx.lineWidth = 2;
223-
ctx.strokeStyle = "rgba(0,0,0,0.45)";
224224
ctx.fillStyle = "#fff";
225-
ctx.strokeText(text, textX, textY);
226225
ctx.fillText(text, textX, textY);
227226

228227
ctx.fillStyle = "rgba(255, 255, 255, 0.95)";
@@ -492,7 +491,7 @@ export async function GET() {
492491
// central progress text with outline for readability
493492
const progressText = `${formatNumber(currentXP)} / ${formatNumber(totalXP)}`;
494493
ctx.lineWidth = 1.8;
495-
ctx.strokeStyle = "rgba(0,0,0,0.48)";
494+
496495
ctx.strokeText(progressText, canvas.width / 2, progressBarY + 10);
497496
ctx.fillText(progressText, canvas.width / 2, progressBarY + 10);
498497

app/dashboard/page.jsx

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,48 +6,79 @@ import { motion, AnimatePresence } from "framer-motion";
66
import { LogOut, LayoutDashboard } from "lucide-react"
77
import Page from "@/components/dashboard/page";
88
import ChartAreaDefault from "@/components/dashboard/chart-area";
9+
import Link from "next/link";
910
import { useState, useEffect } from "react";
11+
1012
export default function Dashboard() {
1113
const [imgUrl, setImgUrl] = useState(null);
1214

1315
useEffect(() => {
1416
const fetchImage = async () => {
1517
try {
16-
const res = await fetch('/api/profile-image'); // API يولد الصورة
17-
const blob = await res.blob();
18-
const url = URL.createObjectURL(blob);
19-
setImgUrl(url);
18+
const res = await fetch('/api/profile-image');
19+
const arrayBuffer = await res.arrayBuffer();
20+
const base64 = btoa(
21+
new Uint8Array(arrayBuffer).reduce(
22+
(data, byte) => data + String.fromCharCode(byte),
23+
''
24+
)
25+
);
26+
setImgUrl(`data:image/png;base64,${base64}`);
2027
} catch (e) {
2128
console.error(e);
2229
}
2330
};
24-
31+
2532
fetchImage();
26-
return () => {
27-
if (imgUrl) URL.revokeObjectURL(imgUrl);
28-
};
2933
}, []);
34+
35+
const addCommas = (num) => {
36+
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
37+
};
38+
39+
const formatted = addCommas("1250000")
40+
3041
return (
3142
<Page>
3243

3344
<div className="flex flex-col md:flex-row md:items-center gap-1 md:gap-4 mb-4">
45+
<motion.div
46+
initial={{ opacity: 0, scale: 0.95 }}
47+
animate={{ opacity: 1, scale: 1 }}
48+
transition={{ duration: 0.6, delay: 1 * 0.1 }}>
3449
<h2 className="text-white flex space-x-2 font-medium text-lg md:text-xl">
3550
<LayoutDashboard className="h-6 w-6" />
3651
<span>Overview</span>
3752
</h2>
53+
</motion.div>
54+
<motion.div
55+
initial={{ opacity: 0, scale: 0.95 }}
56+
animate={{ opacity: 1, scale: 1 }}
57+
transition={{ duration: 0.6, delay: 2 * 0.1 }}>
3858
<span className="hidden md:block w-px h-4 bg-[#5b5683]"></span>
39-
59+
</motion.div>
60+
<motion.div
61+
initial={{ opacity: 0, scale: 0.95 }}
62+
animate={{ opacity: 1, scale: 1 }}
63+
transition={{ duration: 0.6, delay: 3 * 0.1 }}>
4064
<span className="text-md text-zinc-400">
4165
The Overview page gives you a quick glance at your most important information and activities, all in one place. It’s designed to help you stay on top of your account without needing to jump between different sections.
4266
</span>
67+
</motion.div>
4368
</div>
69+
<motion.div
70+
initial={{ opacity: 0, scale: 0.95 }}
71+
animate={{ opacity: 1, scale: 1 }}
72+
transition={{ duration: 0.6, delay: 4 * 0.1 }}
73+
>
4474
<hr className="border-[#373450] mb-4" />
75+
</motion.div>
4576

4677
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
4778
<motion.div
4879
initial={{ opacity: 0, scale: 0.95 }}
4980
animate={{ opacity: 1, scale: 1 }}
50-
transition={{ duration: 0.6, delay: 1 * 0.2 }}
81+
transition={{ duration: 0.6, delay: 5 * 0.1 }}
5182
className="bg-[#1b1922]/50 backdrop-blur p-3 sm:p-4 sm:py-2 rounded-md border border-[#2e2b41]"
5283
>
5384
<div className="flex items-center gap-2 justify-between sm:gap-3">
@@ -63,15 +94,15 @@ export default function Dashboard() {
6394
</div>
6495

6596
<p className=" text-xl sm:text-2xl font-semibold break-words">
66-
0
97+
{formatted}
6798
</p>
6899
</motion.div>
69100

70101

71102
<motion.div
72103
initial={{ opacity: 0, scale: 0.95 }}
73104
animate={{ opacity: 1, scale: 1 }}
74-
transition={{ duration: 0.6, delay: 2 * 0.2 }}
105+
transition={{ duration: 0.6, delay: 6 * 0.1 }}
75106
className="bg-[#1b1922]/50 backdrop-blur p-3 sm:p-4 sm:py-2 rounded-md border border-[#2e2b41]"
76107
>
77108
<div className="flex items-center gap-2 justify-between sm:gap-3">
@@ -87,14 +118,14 @@ export default function Dashboard() {
87118
</div>
88119

89120
<p className=" text-xl sm:text-2xl font-semibold break-words">
90-
0
121+
45
91122
</p>
92123
</motion.div>
93124

94125
<motion.div
95126
initial={{ opacity: 0, scale: 0.95 }}
96127
animate={{ opacity: 1, scale: 1 }}
97-
transition={{ duration: 0.6, delay: 3 * 0.2 }}
128+
transition={{ duration: 0.6, delay: 7 * 0.1 }}
98129
className="bg-[#1b1922]/50 backdrop-blur p-3 sm:p-4 sm:py-2 rounded-md border border-[#2e2b41]"
99130
>
100131
<div className="flex items-center gap-2 justify-between sm:gap-3">
@@ -110,14 +141,14 @@ export default function Dashboard() {
110141
</div>
111142

112143
<p className=" text-xl sm:text-2xl font-semibold break-words">
113-
0
144+
99
114145
</p>
115146
</motion.div>
116147

117148
<motion.div
118149
initial={{ opacity: 0, scale: 0.95 }}
119150
animate={{ opacity: 1, scale: 1 }}
120-
transition={{ duration: 0.6, delay: 4 * 0.2 }}
151+
transition={{ duration: 0.6, delay: 8 * 0.1 }}
121152
className="bg-[#1b1922]/50 backdrop-blur p-3 sm:p-4 sm:py-2 rounded-md border border-[#2e2b41]"
122153
>
123154
<div className="flex items-center gap-2 justify-between sm:gap-3">
@@ -133,7 +164,7 @@ export default function Dashboard() {
133164
</div>
134165

135166
<p className=" text-xl sm:text-2xl font-semibold break-words">
136-
0
167+
#1
137168
</p>
138169
</motion.div>
139170
</div>
@@ -142,7 +173,7 @@ export default function Dashboard() {
142173
<motion.div
143174
initial={{ opacity: 0, scale: 0.95 }}
144175
animate={{ opacity: 1, scale: 1 }}
145-
transition={{ duration: 0.6, delay: 0.4 }}
176+
transition={{ duration: 0.6, delay: 9 * 0.1 }}
146177
className="flex-1 min-w-0"
147178
>
148179
<ChartAreaDefault />
@@ -151,21 +182,32 @@ export default function Dashboard() {
151182
<motion.div
152183
initial={{ opacity: 0, scale: 0.95 }}
153184
animate={{ opacity: 1, scale: 1 }}
154-
transition={{ duration: 0.6, delay: 0.4 }}
185+
transition={{ duration: 0.6, delay: 10 * 0.1 }}
155186
className="flex-shrink-0 w-full lg:w-[420px] xl:w-[500px] h-full"
156187
>
157-
<div className="bg-[#1b1922]/50 border border-[#2e2b41] p-6 rounded-lg flex flex-col items-center md:h-[34.2rem]">
158-
<h3 className="text-xl text-gray-200 font-semibold mb-6">Profile</h3>
188+
<div className="bg-[#1b1922]/50 border border-[#2e2b41] p-6 rounded-lg flex flex-col md:h-[34.5rem]">
189+
<div className="flex justify-between">
190+
<h3 className="text-xl text-gray-200 font-semibold mb-6">Profile</h3>
191+
<div className="group">
192+
<Link href="/dashboard/store/profile" className=" flex space-x-1 p-1.5 bg-[#4f39f65d] rounded-xl cursor-pointer -translate-y-2 border-2 border-indigo-600 group-hover:bg-indigo-600 transition-all duration-300 ">
193+
<svg xmlns="http://www.w3.org/2000/svg" width={24} height={24} viewBox="0 0 24 24"><g fill="currentColor" fillRule="evenodd" clipRule="evenodd"><path d="M11.32 6.176H5c-1.105 0-2 .949-2 2.118v10.588C3 20.052 3.895 21 5 21h11c1.105 0 2-.948 2-2.118v-7.75l-3.914 4.144A2.46 2.46 0 0 1 12.81 16l-2.681.568c-1.75.37-3.292-1.263-2.942-3.115l.536-2.839c.097-.512.335-.983.684-1.352z"></path><path d="M19.846 4.318a2.2 2.2 0 0 0-.437-.692a2 2 0 0 0-.654-.463a1.92 1.92 0 0 0-1.544 0a2 2 0 0 0-.654.463l-.546.578l2.852 3.02l.546-.579a2.1 2.1 0 0 0 .437-.692a2.24 2.24 0 0 0 0-1.635M17.45 8.721L14.597 5.7L9.82 10.76a.54.54 0 0 0-.137.27l-.536 2.84c-.07.37.239.696.588.622l2.682-.567a.5.5 0 0 0 .255-.145l4.778-5.06Z"></path></g></svg>
194+
<span className="mt-1">Edit Profile</span>
195+
</Link>
196+
</div>
197+
</div>
159198

160199
{imgUrl ? (
161200
<img
162201
src={imgUrl}
163202
alt="Profile Image"
164-
className="w-full h-full max-h-[550px] rounded-lg object-cover shadow-lg transition-transform hover:scale-[1.03] duration-300"
203+
draggable={false}
204+
onContextMenu={(e) => e.preventDefault()}
205+
className="w-full select-none h-full max-h-[550px] rounded-lg object-cover shadow-lg transition-transform hover:scale-[1.03] duration-300"
165206
/>
166207
) : (
167208
<div className="w-full h-full max-h-[550px] bg-[#2a2835] rounded-lg animate-pulse" />
168209
)}
210+
169211
</div>
170212
</motion.div>
171213
</div>

app/layout.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ export default function RootLayout({ children }) {
2020
<meta name="theme-color" content="#4f39f6" />
2121

2222
{/* Favicon */}
23-
<link rel="icon" href="/assests/logo1.png" />
23+
<link rel="icon" href="/assets/logo1.png" />
2424

2525
{/* Open Graph (social sharing preview) */}
2626
<meta property="og:title" content="Muzzle Bot" />
2727
<meta property="og:description" content="Muzzle - Discord bot for Fun, Memes, Images, Giveaway, Economy and Anime! Muzzle serve over 117 commands!" />
28-
<meta property="og:image" content="/assests/banner.png" />
28+
<meta property="og:image" content="/assets/banner.png" />
2929
<meta property="og:type" content="website" />
3030
<meta property="og:url" content="https://muzzlebot.xyz/" />
3131

3232
{/* Twitter card */}
3333
<meta name="twitter:card" content="summary_large_image" />
3434
<meta name="twitter:title" content="Muzzle Bot" />
3535
<meta name="twitter:description" content="Muzzle - Discord bot for Fun, Memes, Images, Giveaway, Economy and Anime! Muzzle serve over 117 commands!" />
36-
<meta name="twitter:image" content="/assests/banner.png" />
36+
<meta name="twitter:image" content="/assets/banner.png" />
3737
</head>
3838
<body
3939
className={`tfont custom-scrollbar`}

app/page.jsx

Lines changed: 11 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,15 @@
1-
import Image from "next/image";
2-
3-
export default function Home() {
1+
import { Particles } from "@/components/particles";
2+
export default function ParticlesBasic() {
43
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-
app/page.js
20-
</code>
21-
.
22-
</li>
23-
<li className="tracking-[-.01em]">
24-
Save and see your changes instantly.
25-
</li>
26-
</ol>
27-
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>
52-
</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>
4+
<div className="relative flex h-screen w-full flex-col items-center justify-center overflow-hidden rounded-lg border bg-slate-900 dark:bg-zinc-950 md:shadow-xl">
5+
6+
<Particles
7+
className="absolute inset-0"
8+
quantity={100}
9+
ease={80}
10+
color="#ffffff"
11+
refresh
12+
/>
10113
</div>
10214
);
10315
}

0 commit comments

Comments
 (0)