From 213d83ab4260cdd9cd44eeced1fda36444c21c81 Mon Sep 17 00:00:00 2001 From: Takudzwa-Mlambo <157640942+Cod3Uchiha@users.noreply.github.com> Date: Sun, 9 Aug 2026 07:53:56 +0200 Subject: [PATCH 1/4] Add Supabase client --- src/supabase.js | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/supabase.js diff --git a/src/supabase.js b/src/supabase.js new file mode 100644 index 0000000..337b18f --- /dev/null +++ b/src/supabase.js @@ -0,0 +1,6 @@ +import { createClient } from '@supabase/supabase-js' + +const SUPABASE_URL = 'https://xevezwgeljeyorkkumhu.supabase.co' +const SUPABASE_PUBLISHABLE_KEY = 'sb_publishable_kvMIifHrNIQEI9FJshT1fA_TYFzV__p' + +export const supabase = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY) From bda73b63d5088c84661a8d78fa6d70c39605f54f Mon Sep 17 00:00:00 2001 From: Takudzwa-Mlambo <157640942+Cod3Uchiha@users.noreply.github.com> Date: Sun, 9 Aug 2026 07:54:03 +0200 Subject: [PATCH 2/4] Add Supabase auth dependency --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index ffe6e6b..7d75976 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "preview": "vite preview" }, "dependencies": { + "@supabase/supabase-js": "2.110.9", "react": "19.1.1", "react-dom": "19.1.1" }, From 66b6e32e80674cf1a6ca7a26f1b1953e4cf2ea2c Mon Sep 17 00:00:00 2001 From: Takudzwa-Mlambo <157640942+Cod3Uchiha@users.noreply.github.com> Date: Sun, 9 Aug 2026 07:55:23 +0200 Subject: [PATCH 3/4] Add login user dashboard and admin dashboard --- src/App.jsx | 448 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 397 insertions(+), 51 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 3992cd6..4595eb8 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,92 +1,438 @@ -import { useEffect, useRef } from 'react' +import { useEffect, useRef, useState } from 'react' +import { supabase } from './supabase.js' + +const ADMIN_EMAIL = 'dev@cod3uchiha.com' +const API_URL = 'https://api.cod3uchiha.com' + +function useHashRoute() { + const read = () => window.location.hash.replace(/^#\/?/, '') || 'home' + const [route, setRoute] = useState(read) + + useEffect(() => { + const onHashChange = () => setRoute(read()) + window.addEventListener('hashchange', onHashChange) + return () => window.removeEventListener('hashchange', onHashChange) + }, []) + + return route +} + +function AuthModal({ open, onClose }) { + const [mode, setMode] = useState('signin') + const [email, setEmail] = useState('') + const [password, setPassword] = useState('') + const [loading, setLoading] = useState(false) + const [message, setMessage] = useState('') + const [error, setError] = useState('') + + useEffect(() => { + if (!open) { + setPassword('') + setMessage('') + setError('') + } + }, [open]) + + if (!open) return null + + async function submit(event) { + event.preventDefault() + setLoading(true) + setMessage('') + setError('') + + try { + if (mode === 'signup') { + const { data, error: signUpError } = await supabase.auth.signUp({ email, password }) + if (signUpError) throw signUpError + if (data.session) { + onClose() + window.location.hash = 'dashboard' + } else { + setMessage('Account created. Check your email to confirm it, then sign in.') + } + } else { + const { error: signInError } = await supabase.auth.signInWithPassword({ email, password }) + if (signInError) throw signInError + onClose() + window.location.hash = 'dashboard' + } + } catch (authError) { + setError(authError.message || 'Authentication failed.') + } finally { + setLoading(false) + } + } + + return ( +
+ +
+ +
+ + + {error &&

{error}

} + {message &&

{message}

} + +
+ + + + + ) +} function Story() { return (

The Uchiha Clan and Coding

-

- The Uchiha Clan is renowned for their exceptional abilities and Sharingan eye technique. In the world of coding, we strive to develop our own unique skills and techniques, just like the Uchiha Clan. -

-

- Programming and developing, like the Sharingan, allow us to perceive and understand the intricacies of technology. With each line of code we write, we unlock new possibilities and shape the digital world around us. -

-

- As the Uchiha Clan sought to protect and advance their abilities, we, as developers, aim to use our coding skills to create innovative solutions, build amazing projects, and contribute to the ever-evolving field of technology. -

+

The Uchiha Clan is renowned for their exceptional abilities and Sharingan eye technique. In the world of coding, we strive to develop our own unique skills and techniques, just like the Uchiha Clan.

+

Programming and developing, like the Sharingan, allow us to perceive and understand the intricacies of technology. With each line of code we write, we unlock new possibilities and shape the digital world around us.

+

As the Uchiha Clan sought to protect and advance their abilities, we, as developers, aim to use our coding skills to create innovative solutions, build amazing projects, and contribute to the ever-evolving field of technology.

) } function AudioControls() { const audioRef = useRef(null) + return ( +
+
+ ) +} + +function Home({ session, openAuth }) { + return ( +
+
+
+ Developer · APIs · Open source +

Code Uchiha

+

Build with the Cod3Uchiha API. Accounts include 15 successful API requests every day across the entire endpoint catalog.

+
+ Browse APIs + {session ? ( + Dashboard + ) : ( + + )} +
+

Browsing the site and endpoint catalog stays public. Login is only needed for account features and API usage.

+
+
+ Uchiha Clan +
+
+ +
+
15successful requests / day
+
Allendpoints share one quota
+
0failed requests counted
+
- const play = () => { - audioRef.current?.play() + + + +
+

Contact me: WhatsApp: +263785028126

+

GitHub: github.com/Cod3Uchiha

+

Telegram: t.me/Code_Uchiha

+
+
+ ) +} + +function Dashboard({ session, openAuth }) { + const [data, setData] = useState(null) + const [loading, setLoading] = useState(true) + const [error, setError] = useState('') + const [keyName, setKeyName] = useState('Default') + const [newKey, setNewKey] = useState('') + const [working, setWorking] = useState(false) + + async function loadDashboard() { + if (!session) return + setLoading(true) + setError('') + try { + const today = new Date().toISOString().slice(0, 10) + const [profileResult, planResult, usageResult, keysResult, endpointResult] = await Promise.all([ + supabase.from('profiles').select('display_name, plan_id, is_banned, total_requests, created_at').single(), + supabase.from('plans').select('id, name, requests_per_day, requests_per_minute, max_api_keys').eq('id', 'free').single(), + supabase.from('usage_daily').select('request_count, last_request_at').eq('usage_date', today).maybeSingle(), + supabase.from('api_keys').select('id, name, key_prefix, created_at, last_used_at, revoked_at, total_requests').order('created_at', { ascending: false }), + supabase.from('usage_endpoint_daily').select('endpoint, request_count').eq('usage_date', today).order('request_count', { ascending: false }).limit(12) + ]) + + const firstError = [profileResult, planResult, usageResult, keysResult, endpointResult].find((result) => result.error)?.error + if (firstError) throw firstError + + setData({ + profile: profileResult.data, + plan: planResult.data, + usage: usageResult.data, + keys: keysResult.data || [], + endpoints: endpointResult.data || [] + }) + } catch (loadError) { + setError(loadError.message || 'Unable to load dashboard.') + } finally { + setLoading(false) + } } - const stop = () => { - const audio = audioRef.current - if (!audio) return + useEffect(() => { + void loadDashboard() + }, [session?.user?.id]) + + async function createKey() { + setWorking(true) + setNewKey('') + setError('') + try { + const { data: created, error: createError } = await supabase.rpc('create_api_key', { p_name: keyName || 'Default' }) + if (createError) throw createError + setNewKey(created?.api_key || '') + await loadDashboard() + } catch (createError) { + setError(createError.message || 'Unable to create API key.') + } finally { + setWorking(false) + } + } - audio.pause() - audio.currentTime = 0 + async function revokeKey(id) { + setWorking(true) + try { + const { error: revokeError } = await supabase.rpc('revoke_api_key', { p_key_id: id }) + if (revokeError) throw revokeError + await loadDashboard() + } catch (revokeError) { + setError(revokeError.message || 'Unable to revoke API key.') + } finally { + setWorking(false) + } } + if (!session) { + return ( +
+

Dashboard

+

Sign in to view your API quota and manage API keys.

+ +
+ ) + } + + if (loading) return

Loading dashboard…

+ if (!data) return

{error || 'Dashboard unavailable.'}

+ + const used = data.usage?.request_count || 0 + const limit = data.plan?.requests_per_day || 15 + const remaining = Math.max(0, limit - used) + const activeKeys = data.keys.filter((key) => !key.revoked_at) + return ( -
-