initial commit
This commit is contained in:
0
frontend/studia/src/App.css
Normal file
0
frontend/studia/src/App.css
Normal file
20
frontend/studia/src/App.tsx
Normal file
20
frontend/studia/src/App.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { useState } from "react";
|
||||
import Landing from "./pages/Landing";
|
||||
// import Dashboard from "./pages/Dashboard";
|
||||
import Dashboard from "./pages/Dashboard"
|
||||
import LoginModal from "./components/LoginModal";
|
||||
|
||||
export default function App() {
|
||||
const [token, setToken] = useState(localStorage.getItem("token"));
|
||||
const [showLogin, setShowLogin] = useState(false);
|
||||
|
||||
if (!token)
|
||||
return (
|
||||
<>
|
||||
<Landing onLogin={() => setShowLogin(true)} />
|
||||
{showLogin && <LoginModal onSuccess={setToken} />}
|
||||
</>
|
||||
);
|
||||
|
||||
return <Dashboard />;
|
||||
}
|
||||
23
frontend/studia/src/components/LoginModal.tsx
Normal file
23
frontend/studia/src/components/LoginModal.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
export default function LoginModal({ onSuccess }: any) {
|
||||
const login = async () => {
|
||||
const res = await fetch("http://localhost:8080/login", { method: "POST" });
|
||||
const data = await res.json();
|
||||
localStorage.setItem("token", data.token);
|
||||
onSuccess(data.token);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/40 flex items-center justify-center">
|
||||
<div className="bg-white rounded-2xl p-8 w-96 shadow-xl">
|
||||
<h2 className="text-2xl font-bold mb-6">Login</h2>
|
||||
<button
|
||||
onClick={login}
|
||||
className="w-full bg-indigo-600 text-white py-3 rounded-xl hover:bg-indigo-700"
|
||||
>
|
||||
Login as Demo
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
frontend/studia/src/index.css
Normal file
1
frontend/studia/src/index.css
Normal file
@@ -0,0 +1 @@
|
||||
@import "tailwindcss";
|
||||
10
frontend/studia/src/main.tsx
Normal file
10
frontend/studia/src/main.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './index.css'
|
||||
import App from './App.tsx'
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
8
frontend/studia/src/pages/Admin.tsx
Normal file
8
frontend/studia/src/pages/Admin.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
export default function Admin() {
|
||||
return (
|
||||
<section className="bg-white rounded-2xl p-6 shadow">
|
||||
<h2 className="text-xl font-semibold mb-2">Admin</h2>
|
||||
<p className="text-gray-600">User & system management (placeholder)</p>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
18
frontend/studia/src/pages/Builder.tsx
Normal file
18
frontend/studia/src/pages/Builder.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
export default function Builder() {
|
||||
return (
|
||||
<section className="bg-white rounded-2xl p-6 shadow">
|
||||
<h2 className="text-xl font-semibold mb-4">Create Cards</h2>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<input className="border p-3 rounded-lg" placeholder="Term" />
|
||||
<input className="border p-3 rounded-lg" placeholder="Definition" />
|
||||
</div>
|
||||
|
||||
<button className="mt-4 bg-indigo-600 text-white px-6 py-2 rounded-lg">
|
||||
Add Card
|
||||
</button>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
14
frontend/studia/src/pages/Dashboard.tsx
Normal file
14
frontend/studia/src/pages/Dashboard.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import Builder from "./Builder";
|
||||
import Learn from "./Learn";
|
||||
import Admin from "./Admin";
|
||||
|
||||
|
||||
export default function Dashboard() {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100 p-6 space-y-10">
|
||||
<Builder />
|
||||
<Learn />
|
||||
<Admin />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
28
frontend/studia/src/pages/Landing.tsx
Normal file
28
frontend/studia/src/pages/Landing.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
export default function Landing({ onLogin }: { onLogin: () => void }) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-indigo-600 to-purple-700 text-white">
|
||||
<div className="max-w-6xl mx-auto px-6 py-24 text-center">
|
||||
<h1 className="text-5xl font-bold mb-6">Cardify</h1>
|
||||
<p className="text-xl opacity-90 mb-12">
|
||||
Learn smarter with flashcards & spaced repetition
|
||||
</p>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-6 mb-12">
|
||||
{["HTTP", "JWT", "REST"].map(t => (
|
||||
<div key={t} className="bg-white/10 p-6 rounded-xl backdrop-blur">
|
||||
<h3 className="font-semibold text-lg">{t}</h3>
|
||||
<p className="opacity-80 mt-2">Sample definition</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={onLogin}
|
||||
className="bg-white text-indigo-700 px-8 py-3 rounded-xl font-semibold hover:scale-105 transition"
|
||||
>
|
||||
Get Started
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
22
frontend/studia/src/pages/Learn.tsx
Normal file
22
frontend/studia/src/pages/Learn.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
export default function Learn() {
|
||||
return (
|
||||
<section className="bg-white rounded-2xl p-6 shadow">
|
||||
<h2 className="text-xl font-semibold mb-4">Learn</h2>
|
||||
|
||||
<div className="bg-indigo-50 p-6 rounded-xl">
|
||||
<h3 className="text-lg font-bold">HTTP</h3>
|
||||
<p className="mt-2">Protocol for web communication</p>
|
||||
|
||||
<div className="mt-4 flex gap-4">
|
||||
<button className="bg-green-500 text-white px-4 py-2 rounded-lg">
|
||||
Correct
|
||||
</button>
|
||||
<button className="bg-red-500 text-white px-4 py-2 rounded-lg">
|
||||
Wrong
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user