aboutsummaryrefslogtreecommitdiffstats
path: root/panel/src/pages
diff options
context:
space:
mode:
Diffstat (limited to 'panel/src/pages')
-rw-r--r--panel/src/pages/Dashboard.jsx52
-rw-r--r--panel/src/pages/LoginPage.jsx62
-rw-r--r--panel/src/pages/ManageAds.jsx74
-rw-r--r--panel/src/pages/RegisterPage.jsx47
-rw-r--r--panel/src/pages/ResetPage.jsx41
-rw-r--r--panel/src/pages/Roles.jsx57
6 files changed, 333 insertions, 0 deletions
diff --git a/panel/src/pages/Dashboard.jsx b/panel/src/pages/Dashboard.jsx
new file mode 100644
index 0000000..d16204d
--- /dev/null
+++ b/panel/src/pages/Dashboard.jsx
@@ -0,0 +1,52 @@
+import React, { useEffect, useRef } from 'react';
+import { Chart, CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend } from 'chart.js';
+import { Bar } from 'react-chartjs-2';
+import Navbar from '../components/Navbar';
+
+Chart.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);
+
+const Dashboard = () => {
+ const userStats = { totalUsers: 100, totalAds: 50, totalRevenue: 5000 };
+
+ const chartData = {
+ labels: ['Users', 'Revenue'],
+ datasets: [
+ {
+ label: 'Statistics',
+ data: [userStats.totalUsers, userStats.totalRevenue],
+ backgroundColor: ['rgba(75,192,192,0.6)', 'rgba(153,102,255,0.6)'],
+ },
+ ],
+ };
+
+ const chartRef = useRef(null);
+
+ useEffect(() => {
+ const chartInstance = chartRef.current.chartInstance;
+
+ return () => {
+ if (chartInstance) {
+ chartInstance.destroy();
+ }
+ };
+ }, []);
+
+ return (
+ <div>
+ <Navbar />
+ <div className="container mt-5">
+ <h4 className="mb-4">Dashboard</h4>
+ <div className="mb-4">
+ <h6>Total Users: {userStats.totalUsers}</h6>
+ <h6>Total Ads: {userStats.totalAds}</h6>
+ <h6>Total Revenue: {userStats.totalRevenue}</h6>
+ </div>
+ <div>
+ <Bar ref={chartRef} data={chartData} />
+ </div>
+ </div>
+ </div>
+ );
+};
+
+export default Dashboard;
diff --git a/panel/src/pages/LoginPage.jsx b/panel/src/pages/LoginPage.jsx
new file mode 100644
index 0000000..f763325
--- /dev/null
+++ b/panel/src/pages/LoginPage.jsx
@@ -0,0 +1,62 @@
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom'; // Import useNavigate
+import { signInWithEmailAndPassword } from 'firebase/auth';
+import { auth } from '../firebase';
+
+const LoginPage = () => {
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [error, setError] = useState('');
+ const navigate = useNavigate(); // Get the navigation function
+
+ const handleLogin = async () => {
+ console.log('Attempting login...');
+ console.log('Email:', email);
+ console.log('Password:', password);
+
+ if (password.length < 8) {
+ setError('The password should be minimum 8 digits');
+ console.log('Error:', 'The password should be minimum 8 digits');
+ return;
+ }
+
+ try {
+ await signInWithEmailAndPassword(auth, email, password);
+ console.log('Login successful');
+ navigate('/dashboard'); // Redirect to the dashboard after successful login
+ } catch (error) {
+ setError(error.message);
+ console.log('Error:', error.message);
+ }
+ };
+
+ return (
+ <div className="container mx-auto flex items-center justify-center min-h-screen bg-gray-100">
+ <div className="bg-white p-6 rounded shadow-md w-full max-w-sm">
+ <h4 className="mb-4 text-center">Login</h4>
+ <div className="mb-4">
+ <label>Email</label>
+ <input
+ type="email"
+ value={email}
+ onChange={(e) => setEmail(e.target.value)}
+ className="form-control"
+ />
+ </div>
+ <div className="mb-4">
+ <label>Password</label>
+ <input
+ type="password"
+ value={password}
+ onChange={(e) => setPassword(e.target.value)}
+ className="form-control"
+ />
+ </div>
+ {error && <p className="text-danger">{error}</p>}
+ <button onClick={handleLogin} className="btn btn-primary w-full">Login</button>
+ </div>
+ </div>
+ );
+};
+
+export default LoginPage;
diff --git a/panel/src/pages/ManageAds.jsx b/panel/src/pages/ManageAds.jsx
new file mode 100644
index 0000000..70142d2
--- /dev/null
+++ b/panel/src/pages/ManageAds.jsx
@@ -0,0 +1,74 @@
+import React, { useState, useEffect } from 'react';
+import { db } from '../firebase';
+import { collection, addDoc, getDocs } from 'firebase/firestore';
+import Navbar from '../components/Navbar';
+
+const ManageAds = () => {
+ const [ads, setAds] = useState([]);
+ const [newAd, setNewAd] = useState({ title: '', description: '', imageUrl: '' });
+
+ useEffect(() => {
+ fetchAds();
+ }, []);
+
+ const fetchAds = async () => {
+ const querySnapshot = await getDocs(collection(db, 'ads'));
+ const adsData = querySnapshot.docs.map(doc => doc.data());
+ setAds(adsData);
+ };
+
+ const handleAddAd = async () => {
+ await addDoc(collection(db, 'ads'), newAd);
+ fetchAds();
+ };
+
+ return (
+ <div>
+ <Navbar />
+ <div className="container mt-5">
+ <h4>Manage Ads</h4>
+ <div className="mb-4">
+ <div className="mb-3">
+ <label>Title</label>
+ <input
+ type="text"
+ value={newAd.title}
+ onChange={(e) => setNewAd({ ...newAd, title: e.target.value })}
+ className="form-control"
+ />
+ </div>
+ <div className="mb-3">
+ <label>Description</label>
+ <input
+ type="text"
+ value={newAd.description}
+ onChange={(e) => setNewAd({ ...newAd, description: e.target.value })}
+ className="form-control"
+ />
+ </div>
+ <div className="mb-3">
+ <label>Image URL</label>
+ <input
+ type="text"
+ value={newAd.imageUrl}
+ onChange={(e) => setNewAd({ ...newAd, imageUrl: e.target.value })}
+ className="form-control"
+ />
+ </div>
+ <button onClick={handleAddAd} className="btn btn-primary">Add Ad</button>
+ </div>
+ <div>
+ {ads.map((ad, index) => (
+ <div key={index} className="mb-3">
+ <h5>{ad.title}</h5>
+ <p>{ad.description}</p>
+ <img src={ad.imageUrl} alt={ad.title} className="img-fluid" />
+ </div>
+ ))}
+ </div>
+ </div>
+ </div>
+ );
+};
+
+export default ManageAds;
diff --git a/panel/src/pages/RegisterPage.jsx b/panel/src/pages/RegisterPage.jsx
new file mode 100644
index 0000000..f0b2bba
--- /dev/null
+++ b/panel/src/pages/RegisterPage.jsx
@@ -0,0 +1,47 @@
+import React, { useState } from 'react';
+import { TextField, Button, Container, Typography } from '@mui/material';
+import { createUserWithEmailAndPassword } from 'firebase/auth';
+import { auth } from '../firebase';
+
+const RegisterPage = () => {
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [error, setError] = useState('');
+
+ const handleRegister = async () => {
+ if (password.length < 8) {
+ setError('The password should be minimum 8 digits');
+ return;
+ }
+
+ try {
+ await createUserWithEmailAndPassword(auth, email, password);
+ } catch (error) {
+ setError(error.message);
+ }
+ };
+
+ return (
+ <Container>
+ <Typography variant="h4">Register</Typography>
+ <TextField
+ label="Email"
+ type="email"
+ value={email}
+ onChange={(e) => setEmail(e.target.value)}
+ fullWidth
+ />
+ <TextField
+ label="Password"
+ type="password"
+ value={password}
+ onChange={(e) => setPassword(e.target.value)}
+ fullWidth
+ />
+ {error && <Typography color="error">{error}</Typography>}
+ <Button onClick={handleRegister} variant="contained">Register</Button>
+ </Container>
+ );
+};
+
+export default RegisterPage;
diff --git a/panel/src/pages/ResetPage.jsx b/panel/src/pages/ResetPage.jsx
new file mode 100644
index 0000000..c1750dc
--- /dev/null
+++ b/panel/src/pages/ResetPage.jsx
@@ -0,0 +1,41 @@
+
+import React, { useState } from 'react';
+import { sendPasswordResetEmail } from 'firebase/auth';
+import { auth } from '../firebase';
+
+const ResetPage = () => {
+ const [email, setEmail] = useState('');
+ const [message, setMessage] = useState('');
+ const [error, setError] = useState('');
+
+ const handleReset = async () => {
+ try {
+ await sendPasswordResetEmail(auth, email);
+ setMessage('Reset link sent to your email');
+ } catch (error) {
+ setError(error.message);
+ }
+ };
+
+ return (
+ <div className="container mx-auto flex items-center justify-center min-h-screen bg-gray-100">
+ <div className="bg-white p-6 rounded shadow-md w-full max-w-sm">
+ <h4 className="mb-4 text-center">Reset Password</h4>
+ <div className="mb-4">
+ <label>Email</label>
+ <input
+ type="email"
+ value={email}
+ onChange={(e) => setEmail(e.target.value)}
+ className="form-control"
+ />
+ </div>
+ {error && <p className="text-danger">{error}</p>}
+ {message && <p className="text-success">{message}</p>}
+ <button onClick={handleReset} className="btn btn-primary w-full">Send Reset Link</button>
+ </div>
+ </div>
+ );
+};
+
+export default ResetPage;
diff --git a/panel/src/pages/Roles.jsx b/panel/src/pages/Roles.jsx
new file mode 100644
index 0000000..5b18ace
--- /dev/null
+++ b/panel/src/pages/Roles.jsx
@@ -0,0 +1,57 @@
+import React, { useState, useEffect } from 'react';
+import { db, auth } from '../firebase';
+import { collection, getDocs } from 'firebase/firestore';
+import { httpsCallable } from 'firebase/functions';
+import Navbar from '../components/Navbar';
+
+const Roles = () => {
+ const [users, setUsers] = useState([]);
+ const [loading, setLoading] = useState(true);
+
+ const fetchUsers = async () => {
+ const querySnapshot = await getDocs(collection(db, 'users'));
+ const usersData = querySnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
+ setUsers(usersData);
+ setLoading(false);
+ };
+
+ const handleRoleChange = async (email, newRole) => {
+ const addUserRole = httpsCallable(auth, 'addUserRole');
+ try {
+ await addUserRole({ email: email, role: newRole });
+ fetchUsers();
+ } catch (error) {
+ console.error('Error updating role:', error);
+ }
+ };
+
+ useEffect(() => {
+ fetchUsers();
+ }, []);
+
+ if (loading) {
+ return <p>Loading...</p>;
+ }
+
+ return (
+ <div>
+ <Navbar />
+ <div className="container mt-5">
+ <h4>Manage Roles</h4>
+ <div className="list-group">
+ {users.map((user, index) => (
+ <div key={index} className="list-group-item d-flex justify-content-between align-items-center">
+ <p className="mb-0">{user.email}</p>
+ <div>
+ <button onClick={() => handleRoleChange(user.email, 'admin')} className="btn btn-primary btn-sm mr-2">Make Admin</button>
+ <button onClick={() => handleRoleChange(user.email, 'user')} className="btn btn-secondary btn-sm">Make User</button>
+ </div>
+ </div>
+ ))}
+ </div>
+ </div>
+ </div>
+ );
+};
+
+export default Roles;