Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
|--------------------|---------------------------------------|
| **Frontend** | React + Vite, TypeScript, TailwindCSS |
| **Backend** | Node.js, Express, Socket.IO |
| **Authentication** | Clerk |
| **Authentication** | Supabase |

| **Deployment** | Vercel, Render |
| **Testing** | Jest, Cypress, Postman |

Expand Down Expand Up @@ -109,9 +110,15 @@ For detailed setup instructions, see our **[Development Setup Guide](DEVELOPMENT
git clone https://github.com/subh37106/thunder.git

cd thunder
```

2. **Set up Environment Variables**

Create a `.env.local` file based on `.env.example` and add Supabase credentials provided by the maintainer.

## 📜 License


This project is distributed under the **MIT License**.
See [LICENSE](LICENSE) for details.

Expand All @@ -129,4 +136,4 @@ For help, suggestions, or issues:
👨‍💻 Crafted with ❤️ by **Muneer Ali**

📖 Docs: thunder-docs.vercel.app
🐞 Report Bug: [Issues](https://github.com/Muneerali199/thunder/issues)
🐞 Report Bug: [Issues](https://github.com/Muneerali199/thunder/issues)
2 changes: 2 additions & 0 deletions thunder/frontend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_SUPABASE_URL=your-project-url
VITE_SUPABASE_ANON_KEY=your-anon-key
133 changes: 133 additions & 0 deletions thunder/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions thunder/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@octokit/core": "^6.1.5",
"@react-three/drei": "^9.122.0",
"@react-three/fiber": "8.15.14",
"@supabase/supabase-js": "^2.56.0",
"@types/xml2js": "^0.4.14",
"@webcontainer/api": "^1.6.1",
"axios": "^1.7.8",
Expand Down
22 changes: 12 additions & 10 deletions thunder/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { Builder } from './pages/Builder';
import { Pricing } from './components/Pricing';
import { Checkout } from './components/checkout';
import Footer from './components/Footer';
import { ClerkProvider } from '@clerk/clerk-react';
import Auth from './pages/Auth';


// Declare gtag to avoid TS errors
declare global {
Expand Down Expand Up @@ -38,23 +39,24 @@ function AppRoutes() {
<Route path="/pricing" element={<Pricing />} />
<Route path="/checkout" element={<Checkout />} />
<Route path="/github-callback" element={<Builder />} />
<Route path="/auth" element={<Auth />} />
</Routes>

);
}

function App() {
return (
<ClerkProvider publishableKey={import.meta.env.VITE_CLERK_PUBLISHABLE_KEY}>
<BrowserRouter>
<div className="min-h-screen flex flex-col">
<div className="flex-1">
<AppRoutes />
</div>
<Footer />
<BrowserRouter>
<div className="min-h-screen flex flex-col">
<div className="flex-1">
<AppRoutes />
</div>
</BrowserRouter>
</ClerkProvider>
<Footer />
</div>
</BrowserRouter>
);
}


export default App;
86 changes: 86 additions & 0 deletions thunder/frontend/src/components/SignIn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { useState, useEffect } from 'react';

import { supabase } from '../lib/supabaseClient';

export default function SignIn() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const [validationErrors, setValidationErrors] = useState({
email: '',
password: '',
});

useEffect(() => {
const errors = { email: '', password: '' };
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

if (email && !emailRegex.test(email)) {
errors.email = 'Invalid email address.';
}

if (password && password.length < 6) {
errors.password = 'Password must be at least 6 characters.';
}

setValidationErrors(errors);
}, [email, password]);

const handleSignIn = async (e: React.FormEvent<HTMLFormElement>) => {

e.preventDefault();
setError('');
setLoading(true);

if (!supabase) {
setError('Supabase is not initialized.');
setLoading(false);
return;
}

const { error } = await supabase.auth.signInWithPassword({ email, password });


if (error) {
setError(error.message);
}
setLoading(false);
};

return (
<div>
<h2>Sign In</h2>
<form onSubmit={handleSignIn}>
<input
type="email"
placeholder="Your email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
{validationErrors.email && <p style={{ color: 'red' }}>{validationErrors.email}</p>}
<input
type="password"
placeholder="Your password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
{validationErrors.password && <p style={{ color: 'red' }}>{validationErrors.password}</p>}
<button
type="submit"
disabled={
loading ||
!email ||
!password ||
!!validationErrors.email ||
!!validationErrors.password
}
>
{loading ? 'Loading...' : 'Sign In'}
</button>

</form>
{error && <p>{error}</p>}
</div>
);
}
Loading