diff --git a/.gitignore b/.gitignore index 45e876d..0fc7e9f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ node_modules/ client/node_modules/ server/node_modules/ +__pycache__/ +*.pyc +*.pyo diff --git a/client/src/Dashboard.jsx b/client/src/Dashboard.jsx index 098341c..170806a 100644 --- a/client/src/Dashboard.jsx +++ b/client/src/Dashboard.jsx @@ -1,24 +1,31 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import { getBalance, transferMoney } from "./api"; +import LoadingSpinner from "./components/LoadingSpinner"; function Dashboard() { const [balance, setBalance] = useState(0); const [to, setTo] = useState(""); const [amount, setAmount] = useState(""); + const [loading, setLoading] = useState(true); + const [transferring, setTransferring] = useState(false); useEffect(() => { loadBalance(); }, []); const loadBalance = async () => { + setLoading(true); const data = await getBalance(); setBalance(data.balance); + setLoading(false); }; const handleTransfer = async () => { + setTransferring(true); const data = await transferMoney(to, amount); alert(data.message); - loadBalance(); + await loadBalance(); + setTransferring(false); }; const logout = () => { @@ -29,12 +36,26 @@ function Dashboard() { return (

Dashboard

-

Balance: ₹{balance}

+ + {loading ? ( + + ) : ( +

Balance: ₹{balance}

+ )}

Transfer Money

- setTo(e.target.value)} /> - setAmount(e.target.value)} /> - + setTo(e.target.value)} + /> + setAmount(e.target.value)} + /> +

@@ -42,4 +63,4 @@ function Dashboard() { ); } -export default Dashboard; \ No newline at end of file +export default Dashboard; diff --git a/client/src/api.js b/client/src/api.js index 4222508..e339a2e 100644 --- a/client/src/api.js +++ b/client/src/api.js @@ -28,6 +28,11 @@ export const getBalance = async () => { return res.json(); }; +export const getPosts = async () => { + const res = await fetch(`${API_URL}/api/posts`); + return res.json(); +}; + export const transferMoney = async (to, amount) => { const token = localStorage.getItem("token"); const res = await fetch(`${API_URL}/api/transfer`, { diff --git a/client/src/components/LoadingSpinner.jsx b/client/src/components/LoadingSpinner.jsx new file mode 100644 index 0000000..c222560 --- /dev/null +++ b/client/src/components/LoadingSpinner.jsx @@ -0,0 +1,9 @@ +import styles from './LoadingSpinner.module.css'; + +export default function LoadingSpinner() { + return ( +
+
+
+ ); +} diff --git a/client/src/components/LoadingSpinner.module.css b/client/src/components/LoadingSpinner.module.css new file mode 100644 index 0000000..ffc1560 --- /dev/null +++ b/client/src/components/LoadingSpinner.module.css @@ -0,0 +1,21 @@ +.wrapper { + display: flex; + justify-content: center; + align-items: center; + padding: 2rem; +} + +.spinner { + width: 40px; + height: 40px; + border: 4px solid #e0e0e0; + border-top-color: #333; + border-radius: 50%; + animation: spin 0.75s linear infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} diff --git a/client/src/pages/Home.jsx b/client/src/pages/Home.jsx index 90d2fff..1719abb 100644 --- a/client/src/pages/Home.jsx +++ b/client/src/pages/Home.jsx @@ -1,10 +1,41 @@ -import React from 'react'; +import { useState, useEffect } from "react"; +import { getPosts } from "../api"; +import LoadingSpinner from "../components/LoadingSpinner"; function Home() { + const [posts, setPosts] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + getPosts() + .then((data) => setPosts(data || [])) + .catch(() => setError("Failed to load posts.")) + .finally(() => setLoading(false)); + }, []); + return ( -
-

Welcome to DevStations E-Learning Platform

-
+
+

+ Welcome to DevStations E-Learning Platform +

+ + {loading && } + + {error &&

{error}

} + + {!loading && !error && posts.length === 0 &&

No posts yet.

} + + {posts.map((post) => ( +
+

{post.title}

+

{post.body}

+
+ ))} +
); }