Removed unused folders such as node_modules, frontend, and files package-lock. Also modified readme.
@@ -1,24 +0,0 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
@@ -1,8 +0,0 @@
|
||||
# React + Vite
|
||||
|
||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||
|
||||
Currently, two official plugins are available:
|
||||
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||
@@ -1,38 +0,0 @@
|
||||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import react from 'eslint-plugin-react'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
|
||||
export default [
|
||||
{ ignores: ['dist'] },
|
||||
{
|
||||
files: ['**/*.{js,jsx}'],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
ecmaFeatures: { jsx: true },
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
settings: { react: { version: '18.3' } },
|
||||
plugins: {
|
||||
react,
|
||||
'react-hooks': reactHooks,
|
||||
'react-refresh': reactRefresh,
|
||||
},
|
||||
rules: {
|
||||
...js.configs.recommended.rules,
|
||||
...react.configs.recommended.rules,
|
||||
...react.configs['jsx-runtime'].rules,
|
||||
...reactHooks.configs.recommended.rules,
|
||||
'react/jsx-no-target-blank': 'off',
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/images/logo.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Crop Compass</title>
|
||||
<link
|
||||
href="https://cdn.jsdelivr.net/npm/flowbite@2.5.1/dist/flowbite.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/flowbite@2.5.1/dist/flowbite.min.js"></script>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@reduxjs/toolkit": "^2.2.7",
|
||||
"apexcharts": "^4.5.0",
|
||||
"chart.js": "^4.4.8",
|
||||
"flowbite": "^2.5.1",
|
||||
"react-apexcharts": "^1.7.0",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
"@splinetool/react-spline": "^4.0.0",
|
||||
"flowbite": "^2.5.1",
|
||||
"framer-motion": "^12.4.7",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-icons": "^5.3.0",
|
||||
"react-intersection-observer": "^9.15.1",
|
||||
"react-player": "^2.16.0",
|
||||
"react-redux": "^9.1.2",
|
||||
"react-router-dom": "^6.26.1",
|
||||
"react-typewriter-effect": "^1.1.0",
|
||||
"socket.io-client": "^4.7.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^9.9.0",
|
||||
"eslint-plugin-react": "^7.35.0",
|
||||
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.9",
|
||||
"globals": "^15.9.0",
|
||||
"postcss": "^8.4.45",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"vite": "^5.4.1"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
|
Before Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 136 KiB |
@@ -1 +0,0 @@
|
||||
<svg viewBox="-2.4 -2.4 28.80 28.80" xmlns="http://www.w3.org/2000/svg" fill="#000000" stroke="#000000"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" stroke="#CCCCCC" stroke-width="3.2640000000000002"> <title></title> <g id="Complete"> <g id="add-square"> <g> <rect data-name="--Rectangle" fill="none" height="20" id="_--Rectangle" rx="2" ry="2" stroke="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.4" width="20" x="2" y="2"></rect> <line fill="none" stroke="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.4" x1="15.5" x2="8.5" y1="12" y2="12"></line> <line fill="none" stroke="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.4" x1="12" x2="12" y1="15.5" y2="8.5"></line> </g> </g> </g> </g><g id="SVGRepo_iconCarrier"> <title></title> <g id="Complete"> <g id="add-square"> <g> <rect data-name="--Rectangle" fill="none" height="20" id="_--Rectangle" rx="2" ry="2" stroke="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.4" width="20" x="2" y="2"></rect> <line fill="none" stroke="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.4" x1="15.5" x2="8.5" y1="12" y2="12"></line> <line fill="none" stroke="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.4" x1="12" x2="12" y1="15.5" y2="8.5"></line> </g> </g> </g> </g></svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 482 KiB |
|
Before Width: | Height: | Size: 143 B |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 510 KiB |
|
Before Width: | Height: | Size: 510 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 31 KiB |
@@ -1,12 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path d="M 37.712 41.541 c -2.437 -10.14 2.919 -19.609 8.772 -25.137 c -6.221 11.54 -7.41 20.104 -3.461 33.177 l 2.29 -0.854 c -0.882 -2.464 -1.413 -4.873 -1.685 -7.241 c 8.23 -2.355 13.883 -7.209 15.231 -15.926 C 59.796 13.651 52.042 6.72 43.718 0.117 c 3.04 9.758 -11.581 17.964 -10.296 30.949 c 0.271 2.741 0.697 5.33 1.326 7.825" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(127,178,65); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path d="M 34.069 30.999 c 0.917 -12.923 13.599 -21.098 9.649 -30.883 c 1.394 8.216 -9.771 12.38 -12.663 22.195 c -1.575 5.836 -1.151 11.452 3.693 16.579 C 34.119 36.396 33.937 33.751 34.069 30.999 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(113,156,64); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<polygon points="68.77,61.09 70.46,47.61 43.69,47.61 19.54,47.61 21.23,61.09 " style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(160,126,99); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) "/>
|
||||
<polyline points="63.11,61.09 59.5,90 44.01,90 30.5,90 26.89,61.09 " style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(160,126,99); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) "/>
|
||||
<polygon points="62.61,65.09 63.11,61.09 26.89,61.09 27.39,65.09 " style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(145,107,77); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 307 KiB |
|
Before Width: | Height: | Size: 779 KiB |
@@ -1,74 +0,0 @@
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import "./App.css";
|
||||
//import Navbar from "./components/Navbar";
|
||||
import Navbar2 from "./components/Navbar2";
|
||||
import { useEffect } from "react";
|
||||
import { userSliceActions } from "./store/userSlice";
|
||||
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { BACKEND_URL } from "./constants";
|
||||
|
||||
function App() {
|
||||
const user = useSelector((store) => store.user);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const loader = useSelector((store) => store.loader);
|
||||
|
||||
useEffect(() => {
|
||||
async function initialiseUser() {
|
||||
if (user.role == "unloggeduser") {
|
||||
const responce = await fetch(`${BACKEND_URL}/api/v1/getuser`, {
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
});
|
||||
|
||||
const userData = await responce.json();
|
||||
|
||||
//console.log("User Datae is ", userData);
|
||||
|
||||
dispatch(userSliceActions.addUser(userData.data));
|
||||
|
||||
//console.log("Updated User is : ", user);
|
||||
}
|
||||
}
|
||||
initialiseUser();
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<div className="w-full h-auto flex-col relative">
|
||||
<Navbar2 />
|
||||
<Outlet />
|
||||
<div
|
||||
className={`${
|
||||
loader ? "block" : "hidden"
|
||||
} absolute w-full h-full bg-black opacity-50 top-0 left-0`}
|
||||
>
|
||||
<div class="text-center my-96">
|
||||
<div role="status">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="inline w-12 h-12 text-gray-200 animate-spin dark:text-gray-600 fill-blue-900"
|
||||
viewBox="0 0 100 101"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
||||
fill="currentFill"
|
||||
/>
|
||||
</svg>
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -1,11 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const Container = ({ children }) => {
|
||||
return (
|
||||
<>
|
||||
<div className="w-full h-auto">{children}</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Container;
|
||||
@@ -1,61 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import Td from "./Td";
|
||||
|
||||
const FarmList = () => {
|
||||
const [data, setData] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
useEffect(() => {
|
||||
fetch("http://localhost:8000/api/v1/farm", {
|
||||
credentials: "include",
|
||||
method: "GET",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => setData(data))
|
||||
.then(setLoading(false))
|
||||
.catch((error) => console.error(error));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="relative overflow-x-auto shadow-md sm:rounded-lg">
|
||||
{loading ? (
|
||||
<div>Loading...</div>
|
||||
) : (
|
||||
<table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
||||
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Farm name
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Location
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Type
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Size (acres)
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Action
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.length > 0 ? (
|
||||
data.map((item) => <Td key={item.id} children={item} />)
|
||||
) : (
|
||||
<tr>
|
||||
<td colSpan={5} className="text-center">
|
||||
No data available
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FarmList;
|
||||
@@ -1,69 +0,0 @@
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const Logs = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="relative overflow-y-hidden">
|
||||
<table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 border">
|
||||
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Product name
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Color
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Category
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Price
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200">
|
||||
<th
|
||||
scope="row"
|
||||
className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"
|
||||
>
|
||||
Apple MacBook Pro 17"
|
||||
</th>
|
||||
<td className="px-6 py-4">Silver</td>
|
||||
<td className="px-6 py-4">Laptop</td>
|
||||
<td className="px-6 py-4">$2999</td>
|
||||
</tr>
|
||||
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200">
|
||||
<th
|
||||
scope="row"
|
||||
className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"
|
||||
>
|
||||
Microsoft Surface Pro
|
||||
</th>
|
||||
<td className="px-6 py-4">White</td>
|
||||
<td className="px-6 py-4">Laptop PC</td>
|
||||
<td className="px-6 py-4">$1999</td>
|
||||
</tr>
|
||||
<tr className="bg-white dark:bg-gray-800">
|
||||
<th
|
||||
scope="row"
|
||||
className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"
|
||||
>
|
||||
Magic Mouse 2
|
||||
</th>
|
||||
<td className="px-6 py-4">Black</td>
|
||||
<td className="px-6 py-4">Accessories</td>
|
||||
<td className="px-6 py-4">$99</td>
|
||||
</tr>
|
||||
</tbody>{" "}
|
||||
</table>{" "}
|
||||
<Link to="/logs" className="text-[#2323FF] pl-5">
|
||||
<hr />
|
||||
View all Logs
|
||||
</Link>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Logs;
|
||||
@@ -1,16 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const Message = ({ message }) => {
|
||||
const date = new Date();
|
||||
return (
|
||||
<div className="w-auto h-auto bg-gray-200 rounded-md text-start p-3 mx-4">
|
||||
<p className="">{message}</p>
|
||||
<p className="text-end text-sm ">
|
||||
{date.getDate()}/{date.getMonth()}/{date.getFullYear()}{" "}
|
||||
{date.toLocaleTimeString()}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Message;
|
||||
@@ -1,206 +0,0 @@
|
||||
import React from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import { BACKEND_URL } from "../constants";
|
||||
|
||||
const Navbar = () => {
|
||||
const user = useSelector((store) => store.user);
|
||||
|
||||
//console.log("User is : ", user);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleLogOut = async () => {
|
||||
const responce = await fetch(`${BACKEND_URL}/api/v1/logout`, {
|
||||
method: "Get",
|
||||
credentials: "include",
|
||||
});
|
||||
|
||||
const data = await responce.json();
|
||||
|
||||
//console.log("User Logged out data is : ", data);
|
||||
|
||||
if (data.success == true) {
|
||||
navigate("/user/login");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<nav className="bg-[#3D8D7A] dark:bg-gray-900">
|
||||
<div className="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-4">
|
||||
<a
|
||||
href="/"
|
||||
className="flex items-center space-x-3 rtl:space-x-reverse"
|
||||
>
|
||||
<img
|
||||
src="/images/logo.png"
|
||||
className="size-12 mr-2 "
|
||||
alt="Logo"
|
||||
/>
|
||||
<span className="self-center text-4xl font-bold whitespace-nowrap dark:text-white">
|
||||
Crop Compass
|
||||
</span>
|
||||
</a>
|
||||
<div className="flex items-center md:order-2 space-x-3 md:space-x-0 rtl:space-x-reverse">
|
||||
<button
|
||||
type="button"
|
||||
className="flex text-sm bg-white rounded-full md:me-0 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600"
|
||||
id="user-menu-button"
|
||||
aria-expanded="false"
|
||||
data-dropdown-toggle="user-dropdown"
|
||||
data-dropdown-placement="bottom"
|
||||
>
|
||||
<span className="sr-only">Open user menu</span>
|
||||
<img
|
||||
className="size-9 rounded-full"
|
||||
src={`${user?.avatar}`}
|
||||
alt="user photo"
|
||||
/>
|
||||
</button>
|
||||
{/* <!-- Dropdown menu --> */}
|
||||
<div
|
||||
className="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow dark:bg-gray-700 dark:divide-gray-600 cursor-pointer"
|
||||
id="user-dropdown"
|
||||
>
|
||||
{user?.name !== "Unloggedin User" && (
|
||||
<div className="px-4 py-3">
|
||||
<span className="block text-sm text-gray-900 dark:text-white">
|
||||
{user?.name}
|
||||
</span>
|
||||
<span className="block text-sm text-gray-500 truncate dark:text-gray-400">
|
||||
{user?.email}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ul className="py-2" aria-labelledby="user-menu-button">
|
||||
{user?.name !== "Unloggedin User" && (
|
||||
<>
|
||||
<li>
|
||||
<Link
|
||||
to={"/user/dashboard"}
|
||||
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||
>
|
||||
Dashboard
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
to={"/user/dashboard/settings"}
|
||||
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||
>
|
||||
Settings
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||
>
|
||||
Earnings
|
||||
</a>
|
||||
</li>
|
||||
</>
|
||||
)}
|
||||
|
||||
{user?.name === "Unloggedin User" ? (
|
||||
<li>
|
||||
<Link
|
||||
to={"/user/login"}
|
||||
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||
>
|
||||
Sign In
|
||||
</Link>
|
||||
</li>
|
||||
) : (
|
||||
<li>
|
||||
<a
|
||||
onClick={handleLogOut}
|
||||
className="block px-4 py-2 text-sm text-[#FBFFE4] hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||
>
|
||||
Sign out
|
||||
</a>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<button
|
||||
data-collapse-toggle="navbar-user"
|
||||
type="button"
|
||||
className="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"
|
||||
aria-controls="navbar-user"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<span className="sr-only">Open main menu</span>
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 17 14"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M1 1h15M1 7h15M1 13h15"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="items-center justify-between hidden w-full md:flex md:w-auto md:order-1"
|
||||
id="navbar-user"
|
||||
>
|
||||
<ul className="flex text-xl flex-col font-medium p-4 md:p-0 mt-4 border border-gray-100 rounded-lg bg-[#A3D1C6] md:space-x-8 rtl:space-x-reverse md:flex-row md:mt-0 md:border-0 md:bg-[#3D8D7A] dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700">
|
||||
<li>
|
||||
<Link
|
||||
to={"/"}
|
||||
className="block py-2 px-3 bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 md:dark:text-blue-500"
|
||||
aria-current="page"
|
||||
>
|
||||
Home
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700"
|
||||
>
|
||||
Services
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700"
|
||||
>
|
||||
Pricing
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700"
|
||||
>
|
||||
Contact
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navbar;
|
||||
@@ -1,100 +0,0 @@
|
||||
const Navbar2 = () => {
|
||||
return (
|
||||
<div className=" flex justify-center rounded-full">
|
||||
<nav className=" h-18 mt-3 mb-3 w-[97.5%] mx-5 fixed z-20 dark:bg-gray-800/30 backdrop-blur-md rounded-full">
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-gray-100/10 to-gray-500/20 pointer-events-none rounded-full"></div>
|
||||
<div className="relative h-full flex items-center justify-between p-4">
|
||||
|
||||
<a
|
||||
href="/"
|
||||
className="flex items-center space-x-3 rtl:space-x-reverse"
|
||||
>
|
||||
<img
|
||||
src="/images/logo.png"
|
||||
className="size-10"
|
||||
alt="Logo"
|
||||
/>
|
||||
<span className="self-center text-2xl text-white font-semibold whitespace-nowrap dark:text-white">
|
||||
Crop Compass
|
||||
</span>
|
||||
</a>
|
||||
<div className="flex md:order-2 space-x-3 md:space-x-0 rtl:space-x-reverse">
|
||||
<button
|
||||
type="button"
|
||||
className="text-black bg-white hover:bg-purple-200 focus:ring-4 focus:outline-none focus:ring-black-300 font-medium rounded-full text-sm py-2 px-4 text-center"
|
||||
>
|
||||
Get started
|
||||
</button>
|
||||
<button
|
||||
data-collapse-toggle="navbar-sticky"
|
||||
type="button"
|
||||
className="inline-flex items-center p-2 w-10 h-10 mt-2 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-purple-400 dark:focus:ring-gray-600"
|
||||
aria-controls="navbar-sticky"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<span className="sr-only">Open main menu</span>
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 17 14"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M1 1h15M1 7h15M1 13h15"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="items-center justify-between hidden w-full md:flex md:w-auto md:order-1"
|
||||
id="navbar-sticky"
|
||||
>
|
||||
<ul className="flex flex-col p-4 md:p-0 mt-4 md:space-x-8 rtl:space-x-reverse md:flex-row md:mt-0 bg-transparent font-bold">
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block py-2 px-3 text-gray-50 rounded-sm md:bg-transparent md:text-gray-50 md:p-0 md:dark:text-gray-50"
|
||||
aria-current="page"
|
||||
>
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block py-2 px-3 text-gray-50 rounded-sm hover:bg-gray-100 md:hover:bg-transparent md:hover:text-gray-50 md:p-0 md:dark:hover:text-gray-100 dark:text-white dark:hover:bg-purple-400 dark:hover:text-white md:dark:hover:bg-transparent "
|
||||
>
|
||||
About
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block py-2 px-3 text-gray-50 rounded-sm hover:bg-gray-100 md:hover:bg-transparent md:hover:text-gray-50 md:p-0 md:dark:hover:text-gray-100 dark:text-white dark:hover:bg-purple-400 dark:hover:text-white md:dark:hover:bg-transparent `0"
|
||||
>
|
||||
Services
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block py-2 px-3 text-gray-50 rounded-sm hover:bg-gray-100 md:hover:bg-transparent md:hover:text-gray-50 md:p-0 md:dark:hover:text-gray-50 dark:text-white dark:hover:bg-purple-400 dark:hover:text-white md:dark:hover:bg-transparent `0"
|
||||
>
|
||||
Contact
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navbar2;
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const Notification = ({ notification }) => {
|
||||
let timeStringToDayName = (dateStr) => {
|
||||
// for getting day name by time string
|
||||
// const dateStr = "2024-09-26T04:31:50.646+00:00";
|
||||
const date = new Date(dateStr);
|
||||
const dayName = date.toLocaleDateString("en-US", { weekday: "long" });
|
||||
//console.log(dayName);
|
||||
return dayName;
|
||||
};
|
||||
|
||||
let timeStringtoRealTime = (utcDateStr) => {
|
||||
// for converting the to get time in am or pm
|
||||
//const utcDateStr = "2024-09-26T04:31:50.646+00:00";
|
||||
const date = new Date(utcDateStr);
|
||||
// India TimeZone is Asia/Kolkata, which is UTC+5:30
|
||||
const options = {
|
||||
timeZone: "Asia/Kolkata",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
second: "numeric",
|
||||
hour12: true,
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
};
|
||||
|
||||
const istDate = date.toLocaleString("en-US", options);
|
||||
//console.log(istDate); // Output: "September 26, 2024, 10:01:50 AM"
|
||||
return istDate;
|
||||
};
|
||||
|
||||
let { message, timestamp, isRead } = notification;
|
||||
|
||||
const realTimeString = timeStringtoRealTime(timestamp);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex items-center justify-between p-4 bg-white shadow rounded-lg"
|
||||
onClick={() => {
|
||||
isRead = true;
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
src="https://placehold.co/40x40"
|
||||
alt="Profile picture of the user who followed you"
|
||||
className="w-10 h-10 rounded-full mr-3"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-gray-900">{message}</p>
|
||||
<p className="text-gray-500">
|
||||
{timeStringToDayName(timestamp)},
|
||||
{realTimeString.substring(21, 26) +
|
||||
" " +
|
||||
realTimeString.substring(30)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<p className="text-gray-500 mr-3">{realTimeString.substring(0, 18)}</p>
|
||||
<span
|
||||
className={`w-3 h-3 bg-blue-600 rounded-full ${isRead && "hidden"}`}
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Notification;
|
||||
@@ -1,30 +0,0 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const Td = ({ children }) => {
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<tr className="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700 border-gray-200">
|
||||
<td
|
||||
className="px-6 py-4"
|
||||
onClick={() => {
|
||||
navigate(`farmpage/${children._id}`);
|
||||
}}
|
||||
>
|
||||
{children.name}
|
||||
</td>
|
||||
<td className="px-6 py-4">{children.location}</td>
|
||||
<td className="px-6 py-4">{children.soilType}</td>
|
||||
<td className="px-6 py-4">{children.size}</td>
|
||||
<td className="px-6 py-4">
|
||||
<a
|
||||
href="#"
|
||||
className="font-medium text-blue-600 dark:text-blue-500 hover:underline"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
||||
export default Td;
|
||||
@@ -1,46 +0,0 @@
|
||||
const TotalSpent = () => {
|
||||
return (
|
||||
<div className="h-full">
|
||||
<a
|
||||
href="#"
|
||||
className="h-full block max-w-sm p-6 bg-no-repeat bg-center bg-cover border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"
|
||||
>
|
||||
<div className="absolute right-0 top-0 h-full w-48 overflow-hidden pointer-events-none">
|
||||
<svg
|
||||
viewBox="0 0 200 800"
|
||||
className="absolute right-0 h-full transform translate-x-16 fill-green-100"
|
||||
>
|
||||
<path d="M0,0 Q100,200 0,400 Q100,600 0,800 L200,800 L200,0 Z" />
|
||||
</svg>
|
||||
<svg
|
||||
viewBox="0 0 200 800"
|
||||
className="absolute right-0 h-full transform translate-x-8 fill-green-200/40"
|
||||
>
|
||||
<path d="M0,0 Q80,200 0,400 Q80,600 0,800 L200,800 L200,0 Z" />
|
||||
</svg>
|
||||
|
||||
<svg
|
||||
viewBox="0 0 100 100"
|
||||
className="absolute right-12 top-20 w-16 h-16 fill-green-300/30"
|
||||
>
|
||||
<path d="M50,0 Q100,50 50,100 Q0,50 50,0 Z" />
|
||||
</svg>
|
||||
<svg
|
||||
viewBox="0 0 100 100"
|
||||
className="absolute right-16 top-48 w-12 h-12 fill-green-400/20"
|
||||
>
|
||||
<path d="M50,0 Q100,50 50,100 Q0,50 50,0 Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h5 className="mb-2 text-4xl font-bold tracking-tight text-gray-900 dark:text-white">
|
||||
100,000
|
||||
</h5>
|
||||
<p className="font-normal text-gray-700 dark:text-gray-400">
|
||||
This is the total cost which you spent on this farm
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TotalSpent;
|
||||
@@ -1,28 +0,0 @@
|
||||
// ActivityFeed.jsx
|
||||
import React from "react";
|
||||
|
||||
const ActivityFeed = () => {
|
||||
// Hard-coded activity feed data
|
||||
const activities = [
|
||||
{
|
||||
id: 1,
|
||||
description: "Farm A reported increased yield",
|
||||
time: "10 mins ago",
|
||||
},
|
||||
{ id: 2, description: "Sensor B recalibrated", time: "20 mins ago" },
|
||||
{ id: 3, description: "Alert triggered on Farm C", time: "30 mins ago" },
|
||||
];
|
||||
|
||||
return (
|
||||
<ul className="space-y-2">
|
||||
{activities.map((activity) => (
|
||||
<li key={activity.id} className="bg-gray-50 p-2 rounded shadow">
|
||||
<p className="text-sm">{activity.description}</p>
|
||||
<span className="text-xs text-gray-500">{activity.time}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
export default ActivityFeed;
|
||||
@@ -1,28 +0,0 @@
|
||||
// AlertsPanel.jsx
|
||||
import React from "react";
|
||||
|
||||
const AlertsPanel = () => {
|
||||
// Hard-coded alerts data
|
||||
const alerts = [
|
||||
{ id: 1, message: "Temperature exceeds threshold", type: "warning" },
|
||||
{ id: 2, message: "New sensor connected", type: "info" },
|
||||
{ id: 3, message: "Power consumption high", type: "warning" },
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
{alerts.map((alert) => (
|
||||
<div
|
||||
key={alert.id}
|
||||
className={`p-2 rounded mb-2 ${
|
||||
alert.type === "warning" ? "bg-red-100" : "bg-blue-100"
|
||||
}`}
|
||||
>
|
||||
<p className="text-sm">{alert.message}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AlertsPanel;
|
||||
@@ -1,13 +0,0 @@
|
||||
// MetricsCard.jsx
|
||||
import React from "react";
|
||||
|
||||
const MetricsCard = ({ title, value }) => {
|
||||
return (
|
||||
<div className="bg-white p-4 rounded-lg shadow">
|
||||
<h3 className="text-gray-500 text-sm font-medium">{title}</h3>
|
||||
<p className="text-2xl font-bold">{value}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MetricsCard;
|
||||
@@ -1,50 +0,0 @@
|
||||
// PerformanceChart.jsx
|
||||
import React from "react";
|
||||
import { Line } from "react-chartjs-2";
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
} from "chart.js";
|
||||
|
||||
ChartJS.register(
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend
|
||||
);
|
||||
|
||||
const PerformanceChart = () => {
|
||||
const data = {
|
||||
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"],
|
||||
datasets: [
|
||||
{
|
||||
label: "Yield",
|
||||
data: [65, 59, 80, 81, 56, 55, 70], // hard-coded values
|
||||
fill: false,
|
||||
backgroundColor: "rgb(75, 192, 192)",
|
||||
borderColor: "rgba(75, 192, 192, 0.2)",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const options = {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: { position: "top" },
|
||||
title: { display: true, text: "Performance Trend" },
|
||||
},
|
||||
};
|
||||
|
||||
return <Line data={data} options={options} />;
|
||||
};
|
||||
|
||||
export default PerformanceChart;
|
||||
@@ -1,46 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import Chart from "react-apexcharts";
|
||||
|
||||
const Piechart = () => {
|
||||
const [series, setSeries] = useState([35.1, 23.5, 2.4, 5.4]);
|
||||
|
||||
const chartOptions = {
|
||||
series: series,
|
||||
labels: ["Fertilizers", "Pestisides", "Manner", "Urea"],
|
||||
colors: ["#1C64F2", "#16BDCA", "#FDBA8C", "#E74694"],
|
||||
chart: {
|
||||
type: "donut",
|
||||
height: 320,
|
||||
},
|
||||
plotOptions: {
|
||||
pie: {
|
||||
donut: {
|
||||
labels: {
|
||||
show: true,
|
||||
total: {
|
||||
show: true,
|
||||
label: "Total",
|
||||
formatter: function (w) {
|
||||
return w.globals.seriesTotals.reduce((a, b) => a + b, 0) + "k";
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
position: "bottom",
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white md:p-6 block max-w-sm p-6 bg-no-repeat bg-center bg-cover border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700">
|
||||
<h5 className="text-xl font-bold text-gray-900 dark:text-white mb-4 ">
|
||||
Cost Analysis
|
||||
</h5>
|
||||
<Chart options={chartOptions} series={series} type="donut" height={320} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Piechart;
|
||||
@@ -1 +0,0 @@
|
||||
export const BACKEND_URL = "http://localhost:8000";
|
||||
@@ -1,26 +0,0 @@
|
||||
import React, { createContext, useMemo, useContext } from "react";
|
||||
import { io } from "socket.io-client";
|
||||
import { BACKEND_URL } from "../constants";
|
||||
|
||||
const SocketContext = createContext(null);
|
||||
|
||||
export const useSocket = () => {
|
||||
const socket = useContext(SocketContext);
|
||||
return socket;
|
||||
};
|
||||
|
||||
export const SocketProvider = (props) => {
|
||||
const socket = useMemo(
|
||||
() =>
|
||||
io(`${BACKEND_URL}`, {
|
||||
withCredentials: true,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<SocketContext.Provider value={socket}>
|
||||
{props.children}
|
||||
</SocketContext.Provider>
|
||||
);
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@theme {
|
||||
--color-midnight: #A3D1C6;
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||||
import App from "./App.jsx";
|
||||
import "./index.css";
|
||||
import { SocketProvider } from "./context/SocketProvider.jsx";
|
||||
|
||||
import { Provider } from "react-redux";
|
||||
import MentifyStore from "./store/index.js";
|
||||
|
||||
import LoginPage from "./pages/Login/LoginPage.jsx";
|
||||
import SignupPage from "./pages/Login/SignupPage.jsx";
|
||||
import MainUserPanel from "./pages/UserPanel/MainUserPanel.jsx";
|
||||
import ForgetPassword from "./pages/Password/ForgetPassword.jsx";
|
||||
import ResetPassword from "./pages/Password/ResetPassword.jsx";
|
||||
|
||||
import HomePage from "./pages/Home/HomePage.jsx";
|
||||
import Dashboard from "./pages/UserPanel/Dashboard.jsx";
|
||||
import History from "./pages/UserPanel/History.jsx";
|
||||
import Notifications from "./pages/UserPanel/Notifications.jsx";
|
||||
import Settings from "./pages/UserPanel/Settings.jsx";
|
||||
import ScheduleMeeting from "./pages/UserPanel/ScheduleMeeting.jsx";
|
||||
import Support from "./pages/UserPanel/Support.jsx";
|
||||
import FeedBackAndRatings from "./pages/UserPanel/FeedBackAndRatings.jsx";
|
||||
import Monitoring from "./pages/UserPanel/Monitoring.jsx";
|
||||
import AddFarm from "./pages/UserPanel/Farm/AddFarm.jsx";
|
||||
import UpdateFarm from "./pages/UserPanel/Farm/UpdateForm.jsx";
|
||||
import FarmPage from "./pages/UserPanel/Farm/FarmPage.jsx";
|
||||
createRoot(document.getElementById("root")).render(
|
||||
<StrictMode>
|
||||
<Provider store={MentifyStore}>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
{/* Routes for the main App */}
|
||||
<Route path="/" element={<App />}>
|
||||
<Route index element={<HomePage />} />
|
||||
<Route path="home" element={<HomePage />} />
|
||||
</Route>
|
||||
|
||||
{/* User related routes */}
|
||||
<Route path="user" element={<App />}>
|
||||
<Route path="login" element={<LoginPage />} />
|
||||
<Route path="signup" element={<SignupPage />} />
|
||||
<Route path="forgetpassword" element={<ForgetPassword />} />
|
||||
<Route
|
||||
path="api/v1/password/reset/:token"
|
||||
element={<ResetPassword />}
|
||||
/>
|
||||
|
||||
<Route path="dashboard" element={<MainUserPanel />}>
|
||||
<Route index element={<Dashboard />} />
|
||||
<Route path="history" element={<History />} />
|
||||
<Route path="notifications" element={<Notifications />} />
|
||||
<Route path="settings" element={<Settings />} />
|
||||
<Route path="scheduledmeetings" element={<ScheduleMeeting />} />
|
||||
<Route path="support" element={<Support />} />
|
||||
<Route path="feedback" element={<FeedBackAndRatings />} />
|
||||
<Route path="monitoring" element={<Monitoring />} />
|
||||
<Route path="addfarm" element={<AddFarm />} />
|
||||
<Route path="updatefarm" element={<UpdateFarm />} />
|
||||
<Route path="farmpage/:farmId" element={<FarmPage />} />
|
||||
</Route>
|
||||
</Route>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
</Provider>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
createRoot(document.getElementById("root")).render(
|
||||
<StrictMode>
|
||||
<Provider store={MentifyStore}>
|
||||
<SocketProvider>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
{/* Routes for the main App */}
|
||||
<Route path="/" element={<App />}>
|
||||
<Route index element={<HomePage />} />
|
||||
<Route path="home" element={<HomePage />} />
|
||||
</Route>
|
||||
|
||||
{/* User related routes */}
|
||||
<Route path="user" element={<App />}>
|
||||
<Route path="login" element={<LoginPage />} />
|
||||
<Route path="signup" element={<SignupPage />} />
|
||||
<Route path="forgetpassword" element={<ForgetPassword />} />
|
||||
<Route
|
||||
path="api/v1/password/reset/:token"
|
||||
element={<ResetPassword />}
|
||||
/>
|
||||
|
||||
<Route path="dashboard" element={<MainUserPanel />}>
|
||||
<Route index element={<Dashboard />} />
|
||||
<Route path="history" element={<History />} />
|
||||
<Route path="notifications" element={<Notifications />} />
|
||||
<Route path="settings" element={<Settings />} />
|
||||
<Route path="scheduledmeetings" element={<ScheduleMeeting />} />
|
||||
<Route path="support" element={<Support />} />
|
||||
<Route path="feedback" element={<FeedBackAndRatings />} />
|
||||
</Route>
|
||||
</Route>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
</SocketProvider>
|
||||
</Provider>
|
||||
</StrictMode>
|
||||
);
|
||||
d;
|
||||
@@ -1,43 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const About = () => {
|
||||
return (
|
||||
<>
|
||||
<section className="bg-white py-12 w-full flex justify-center">
|
||||
<div className="flex flex-col md:flex-row justify-between w-10/12 h-auto">
|
||||
<div className="w-full md:w-4/5 object-contain flex justify-center items-center">
|
||||
<img src="/images/calender.png" className="w-full h-auto" alt="" />
|
||||
</div>
|
||||
<div className="container mx-auto flex flex-col justify-around h-full w-full md:py-10">
|
||||
<div className="text-center md:text-start flex flex-col justify-around h-full">
|
||||
<h2 className="text-xl font-bold mb-4 text-yellow-600">
|
||||
CUSTOMIZE WITH YOUR SCHEDULE
|
||||
</h2>
|
||||
<h1 className="text-2xl md:text-4xl md:font-extrabold font-bold mb-4">
|
||||
Personalized Professional Online Mentor on Your Schedule
|
||||
</h1>
|
||||
<p className="text-base mb-8">
|
||||
Our scheduling system allows you to select based on free time.
|
||||
Lorem ipsum demo text for template. Keep track of your students
|
||||
class and mentoring schedules, and never miss your Session. The
|
||||
best online class scheduling system with easy accessibility.
|
||||
Lorem ipsum is a placeholder text commonly used to demonstrate
|
||||
the visual form
|
||||
</p>
|
||||
<div className="flex gap-4 justify-center md:justify-start">
|
||||
<button
|
||||
type="button"
|
||||
className="focus:outline-none text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg text-base px-5 py-2.5 mb-2 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-900"
|
||||
>
|
||||
Get started
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default About;
|
||||
@@ -1,111 +0,0 @@
|
||||
|
||||
import React from "react";
|
||||
|
||||
export const HeroSecn = () =>{
|
||||
return(
|
||||
<section className=" py-40 w-full flex justify-center text-gray-100">
|
||||
<div className="flex flex-col-reverse md:flex-row justify-between w-10/12 h-auto">
|
||||
<div className="container mx-auto flex flex-col justify-between h-full w-full">
|
||||
<div className="text-center md:text-start flex flex-col justify-around h-full">
|
||||
<h1 className="text-6xl md:text-6xl md:w-2/3 md:font-extrabold font-bold">
|
||||
Anything and Everything you Need to know About
|
||||
</h1>
|
||||
<p className="text-2xl font-semibold mb-8 ">
|
||||
Your crops and their Health!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full md:w-4/5 object-contain flex justify-center items-center">
|
||||
<img src="/images/plant.png" className="w-full h-auto rounded-3xl shadow-xl" alt="plant" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export const CardWithImage = () => {
|
||||
return (
|
||||
<div class="max-w-sm rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700">
|
||||
<a href="#">
|
||||
<img class="rounded-t-lg" src="https://i.pinimg.com/736x/07/2b/5f/072b5f6a1630d919ceee1a8569683cf7.jpg" alt="plant" />
|
||||
</a>
|
||||
<div class="p-6 backdrop-blur-md rounded-b-lg">
|
||||
<a href="#">
|
||||
<h5 class="mb-2 text-2xl font-bold tracking-tight text-white dark:text-white">Excellent Dashboards</h5>
|
||||
</a>
|
||||
<p class="mb-3 font-normal text-white dark:text-gray-400">Our descriptive dashboards give insights into your crop's health and keeps track of your burning expenses</p>
|
||||
<a href="#" class="inline-flex shadow-md backdrop-blur-md bg-gradient-to-tr from-gray-700/20 to-gray-50/20 items-center px-3 py-2 text-sm font-medium text-center text-white rounded-lg hover:backdrop-blur-xl ">
|
||||
Read more
|
||||
<svg class="rtl:rotate-180 w-3.5 h-3.5 ms-2" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5h12m0 0L9 1m4 4L9 9"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const CardOnlyText = () => {
|
||||
return(
|
||||
<div>
|
||||
<a href="#" class="block max-w-sm p-6 rounded-lg shadow-md backdrop-blur-md dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700">
|
||||
<h5 class="mb-2 text-2xl font-bold tracking-tight text-gray-50 dark:text-white">Noteworthy technology acquisitions 2021</h5>
|
||||
<p class="font-normal text-gray-50 dark:text-gray-400">Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.</p>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const CardWithButton = () => {
|
||||
return(
|
||||
<div class="max-w-sm p-6 backdrop-blur-md rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700">
|
||||
<a href="#">
|
||||
<h5 class="mb-2 text-2xl font-bold tracking-tight text-gray-50 dark:text-white">Noteworthy technology acquisitions 2021</h5>
|
||||
</a>
|
||||
<p class="mb-3 font-normal text-gray-50 dark:text-gray-400">Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.</p>
|
||||
<a href="#" class="inline-flex shadow-md backdrop-blur-md bg-gradient-to-tr from-gray-700/20 to-gray-50/20 items-center px-3 py-2 text-sm font-medium text-center text-white rounded-lg hover:backdrop-blur-xl ">
|
||||
Read more
|
||||
<svg class="rtl:rotate-180 w-3.5 h-3.5 ms-2" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5h12m0 0L9 1m4 4L9 9"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const CardWithOnlyImage = () => {
|
||||
return(
|
||||
<div class="w-full max-w-sm bg-white rounded-lg shadow-xl dark:bg-gray-800 dark:border-gray-700">
|
||||
<a href="#">
|
||||
<img class=" rounded-lg" src="/images/plant.png" alt="product image" />
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const cards = [HeroSecn, CardWithImage, CardOnlyText, CardWithButton, CardWithImage];
|
||||
|
||||
export default cards;
|
||||
|
||||
|
||||
export const CardLayout = () => {
|
||||
return(
|
||||
<div>
|
||||
<HeroSecn />
|
||||
<div className=" flex justify-center">
|
||||
<div className=" flex justify-between py-8 w-5/6 ">
|
||||
<cardWithImage />
|
||||
<div className="flex flex-col gap-10 justify-between ">
|
||||
<cardOnlyText />
|
||||
<cardWithButton />
|
||||
</div>
|
||||
|
||||
<div className=" flex flex-col justify-between">
|
||||
<cardWithOnlyImage />
|
||||
<cardOnlyText />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const Customization = () => {
|
||||
return (
|
||||
<>
|
||||
<section
|
||||
className="bg-gray-100 py-12 w-full flex justify-center"
|
||||
style={{ backgroundColor: "#f0f0f0" }}
|
||||
>
|
||||
<div className="flex flex-col-reverse md:flex-row justify-between w-10/12 h-auto">
|
||||
<div className="container mx-auto flex flex-col justify-around h-full w-full md:py-10">
|
||||
<div className="text-center md:text-start flex flex-col justify-around h-full">
|
||||
<h2 className="text-xl font-bold mb-4 text-yellow-600">
|
||||
CUSTOMIZE WITH YOUR SCHEDULE
|
||||
</h2>
|
||||
<h1 className="text-2xl md:text-4xl md:font-extrabold font-bold mb-4">
|
||||
Talented and Qualified Tutors to Serve You for Help
|
||||
</h1>
|
||||
<p className="text-base mb-8">
|
||||
Our scheduling system allows you to select based on free time.
|
||||
Lorem ipsum demo text for template. Keep track of your students
|
||||
class and tutoring schedules, and never miss your lectures. The
|
||||
best online class scheduling system with easy accessibility.
|
||||
Lorem ipsum is a placeholder text commonly used to demonstrate
|
||||
the visual form
|
||||
</p>
|
||||
<div className="flex gap-4 justify-center md:justify-start">
|
||||
<button
|
||||
type="button"
|
||||
className="focus:outline-none text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg text-base px-5 py-2.5 mb-2 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-900"
|
||||
>
|
||||
Get started
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full md:w-4/5 object-contain flex justify-center items-center">
|
||||
<img
|
||||
src="/images/interaction2.png"
|
||||
className="w-full h-auto"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Customization;
|
||||
@@ -1,190 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const Footer = () => {
|
||||
return (
|
||||
<>
|
||||
<footer className="bg-white dark:bg-gray-900">
|
||||
<div className="mx-auto w-full max-w-screen-xl p-4 py-6 lg:py-8">
|
||||
<div className="md:flex md:justify-between">
|
||||
<div className="mb-6 md:mb-0">
|
||||
<a href="https://flowbite.com/" class="flex items-center gap-2">
|
||||
<img
|
||||
src="/images/logo.jpg"
|
||||
className="h-9 rounded-full"
|
||||
alt="Flowbite Logo"
|
||||
/>
|
||||
<span className="self-center text-xl font-bold whitespace-nowrap dark:text-white">
|
||||
MentorFlux
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-8 sm:gap-6 sm:grid-cols-3">
|
||||
<div>
|
||||
<h2 className="mb-6 text-sm font-semibold text-gray-900 uppercase dark:text-white">
|
||||
Resources
|
||||
</h2>
|
||||
<ul className="text-gray-500 dark:text-gray-400 font-medium">
|
||||
<li className="mb-4">
|
||||
<a href="https://flowbite.com/" class="hover:underline">
|
||||
Flowbite
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://tailwindcss.com/" class="hover:underline">
|
||||
Tailwind CSS
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="mb-6 text-sm font-semibold text-gray-900 uppercase dark:text-white">
|
||||
Follow us
|
||||
</h2>
|
||||
<ul className="text-gray-500 dark:text-gray-400 font-medium">
|
||||
<li className="mb-4">
|
||||
<a
|
||||
href="https://github.com/themesberg/flowbite"
|
||||
className="hover:underline "
|
||||
>
|
||||
Github
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://discord.gg/4eeurUVvTy"
|
||||
className="hover:underline"
|
||||
>
|
||||
Discord
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="mb-6 text-sm font-semibold text-gray-900 uppercase dark:text-white">
|
||||
Legal
|
||||
</h2>
|
||||
<ul className="text-gray-500 dark:text-gray-400 font-medium">
|
||||
<li className="mb-4">
|
||||
<a href="#" className="hover:underline">
|
||||
Privacy Policy
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" className="hover:underline">
|
||||
Terms & Conditions
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr className="my-6 border-gray-200 sm:mx-auto dark:border-gray-700 lg:my-8" />
|
||||
<div className="sm:flex sm:items-center sm:justify-between">
|
||||
<span className="text-sm text-gray-500 sm:text-center dark:text-gray-400">
|
||||
© 2024{" "}
|
||||
<a href="https://flowbite.com/" class="hover:underline">
|
||||
MentorFlux™
|
||||
</a>
|
||||
. All Rights Reserved.
|
||||
</span>
|
||||
<div className="flex mt-4 sm:justify-center sm:mt-0">
|
||||
<a
|
||||
href="#"
|
||||
className="text-gray-500 hover:text-gray-900 dark:hover:text-white"
|
||||
>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 8 19"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M6.135 3H8V0H6.135a4.147 4.147 0 0 0-4.142 4.142V6H0v3h2v9.938h3V9h2.021l.592-3H5V3.591A.6.6 0 0 1 5.592 3h.543Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<span className="sr-only">Facebook page</span>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="text-gray-500 hover:text-gray-900 dark:hover:text-white ms-5"
|
||||
>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 21 16"
|
||||
>
|
||||
<path d="M16.942 1.556a16.3 16.3 0 0 0-4.126-1.3 12.04 12.04 0 0 0-.529 1.1 15.175 15.175 0 0 0-4.573 0 11.585 11.585 0 0 0-.535-1.1 16.274 16.274 0 0 0-4.129 1.3A17.392 17.392 0 0 0 .182 13.218a15.785 15.785 0 0 0 4.963 2.521c.41-.564.773-1.16 1.084-1.785a10.63 10.63 0 0 1-1.706-.83c.143-.106.283-.217.418-.33a11.664 11.664 0 0 0 10.118 0c.137.113.277.224.418.33-.544.328-1.116.606-1.71.832a12.52 12.52 0 0 0 1.084 1.785 16.46 16.46 0 0 0 5.064-2.595 17.286 17.286 0 0 0-2.973-11.59ZM6.678 10.813a1.941 1.941 0 0 1-1.8-2.045 1.93 1.93 0 0 1 1.8-2.047 1.919 1.919 0 0 1 1.8 2.047 1.93 1.93 0 0 1-1.8 2.045Zm6.644 0a1.94 1.94 0 0 1-1.8-2.045 1.93 1.93 0 0 1 1.8-2.047 1.918 1.918 0 0 1 1.8 2.047 1.93 1.93 0 0 1-1.8 2.045Z" />
|
||||
</svg>
|
||||
<span className="sr-only">Discord community</span>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="text-gray-500 hover:text-gray-900 dark:hover:text-white ms-5"
|
||||
>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 17"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M20 1.892a8.178 8.178 0 0 1-2.355.635 4.074 4.074 0 0 0 1.8-2.235 8.344 8.344 0 0 1-2.605.98A4.13 4.13 0 0 0 13.85 0a4.068 4.068 0 0 0-4.1 4.038 4 4 0 0 0 .105.919A11.705 11.705 0 0 1 1.4.734a4.006 4.006 0 0 0 1.268 5.392 4.165 4.165 0 0 1-1.859-.5v.05A4.057 4.057 0 0 0 4.1 9.635a4.19 4.19 0 0 1-1.856.07 4.108 4.108 0 0 0 3.831 2.807A8.36 8.36 0 0 1 0 14.184 11.732 11.732 0 0 0 6.291 16 11.502 11.502 0 0 0 17.964 4.5c0-.177 0-.35-.012-.523A8.143 8.143 0 0 0 20 1.892Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<span className="sr-only">Twitter page</span>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="text-gray-500 hover:text-gray-900 dark:hover:text-white ms-5"
|
||||
>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M10 .333A9.911 9.911 0 0 0 6.866 19.65c.5.092.678-.215.678-.477 0-.237-.01-1.017-.014-1.845-2.757.6-3.338-1.169-3.338-1.169a2.627 2.627 0 0 0-1.1-1.451c-.9-.615.07-.6.07-.6a2.084 2.084 0 0 1 1.518 1.021 2.11 2.11 0 0 0 2.884.823c.044-.503.268-.973.63-1.325-2.2-.25-4.516-1.1-4.516-4.9A3.832 3.832 0 0 1 4.7 7.068a3.56 3.56 0 0 1 .095-2.623s.832-.266 2.726 1.016a9.409 9.409 0 0 1 4.962 0c1.89-1.282 2.717-1.016 2.717-1.016.366.83.402 1.768.1 2.623a3.827 3.827 0 0 1 1.02 2.659c0 3.807-2.319 4.644-4.525 4.889a2.366 2.366 0 0 1 .673 1.834c0 1.326-.012 2.394-.012 2.72 0 .263.18.572.681.475A9.911 9.911 0 0 0 10 .333Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<span className="sr-only">GitHub account</span>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="text-gray-500 hover:text-gray-900 dark:hover:text-white ms-5"
|
||||
>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M10 0a10 10 0 1 0 10 10A10.009 10.009 0 0 0 10 0Zm6.613 4.614a8.523 8.523 0 0 1 1.93 5.32 20.094 20.094 0 0 0-5.949-.274c-.059-.149-.122-.292-.184-.441a23.879 23.879 0 0 0-.566-1.239 11.41 11.41 0 0 0 4.769-3.366ZM8 1.707a8.821 8.821 0 0 1 2-.238 8.5 8.5 0 0 1 5.664 2.152 9.608 9.608 0 0 1-4.476 3.087A45.758 45.758 0 0 0 8 1.707ZM1.642 8.262a8.57 8.57 0 0 1 4.73-5.981A53.998 53.998 0 0 1 9.54 7.222a32.078 32.078 0 0 1-7.9 1.04h.002Zm2.01 7.46a8.51 8.51 0 0 1-2.2-5.707v-.262a31.64 31.64 0 0 0 8.777-1.219c.243.477.477.964.692 1.449-.114.032-.227.067-.336.1a13.569 13.569 0 0 0-6.942 5.636l.009.003ZM10 18.556a8.508 8.508 0 0 1-5.243-1.8 11.717 11.717 0 0 1 6.7-5.332.509.509 0 0 1 .055-.02 35.65 35.65 0 0 1 1.819 6.476 8.476 8.476 0 0 1-3.331.676Zm4.772-1.462A37.232 37.232 0 0 0 13.113 11a12.513 12.513 0 0 1 5.321.364 8.56 8.56 0 0 1-3.66 5.73h-.002Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<span className="sr-only">Dribbble account</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
@@ -1,118 +0,0 @@
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const Hero = () => {
|
||||
return (
|
||||
<>
|
||||
<section className="bg-white py-12 w-full flex justify-center">
|
||||
<div className="flex flex-col-reverse md:flex-row justify-between w-10/12 h-auto">
|
||||
<div className="container mx-auto flex flex-col justify-between h-full w-full">
|
||||
<div className="text-center md:text-start flex flex-col gap-5 justify-around h-full">
|
||||
<h2 className="text-xl font-bold mb-4 text-yellow-600">
|
||||
100% SATISFACTION GUARANTEE
|
||||
</h2>
|
||||
<h1 className="text-6xl md:text-8xl md:font-extrabold font-bold mb-4">
|
||||
Find Your Perfect Mentor
|
||||
</h1>
|
||||
<div className="flex gap-4 justify-center md:justify-start">
|
||||
<form class="w-full md:w-3/5">
|
||||
<label
|
||||
for="default-search"
|
||||
class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white"
|
||||
>
|
||||
Search
|
||||
</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 start-0 flex items-center ps-3 pointer-events-none">
|
||||
<svg
|
||||
class="w-4 h-4 text-gray-500 dark:text-gray-400"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<input
|
||||
type="search"
|
||||
id="default-search"
|
||||
class="block w-full p-4 ps-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Search for mentors"
|
||||
required
|
||||
/>
|
||||
<Link
|
||||
to={"/mentor"}
|
||||
type="button"
|
||||
class="text-white absolute end-2.5 bottom-2.5 bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-800"
|
||||
>
|
||||
Find your Mentor
|
||||
</Link>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/*
|
||||
<Link
|
||||
to={"/mentor"}
|
||||
type="button"
|
||||
className="focus:outline-none text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg text-base px-5 py-2.5 mb-2 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-900"
|
||||
>
|
||||
Find your Mentor
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
className="text-white bg-gray-800 hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-gray-800 dark:hover:bg-gray-700 dark:focus:ring-gray-700 dark:border-gray-700"
|
||||
>
|
||||
Contact Us
|
||||
</button> */}
|
||||
</div>
|
||||
<p className="text-lg mb-8 my-6">
|
||||
Find guidance, support, and industry insights from seasoned
|
||||
professionals. Achieve your goals with our mentorship
|
||||
platform.Our platform bridges the gap between students and
|
||||
experienced mentors.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full md:w-4/5 object-contain flex justify-center items-center">
|
||||
<img src="/images/student.png" className="w-full h-auto" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 mt-8">
|
||||
<div className="w-full p-4">
|
||||
<div className="bg-blue-500 rounded-lg p-6 text-center">
|
||||
<h3 className="text-white font-bold text-3xl mb-2">870</h3>
|
||||
<p className="text-white font-bold">Expert tutors</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full p-4">
|
||||
<div className="bg-blue-500 rounded-lg p-6 text-center">
|
||||
<h3 className="text-white font-bold text-3xl mb-2">20,000+</h3>
|
||||
<p className="text-white font-bold">Hours tutored</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full p-4">
|
||||
<div className="bg-blue-500 rounded-lg p-6 text-center">
|
||||
<h3 className="text-white font-bold text-3xl mb-2">298</h3>
|
||||
<p className="text-white font-bold">Subjects and courses</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full p-4">
|
||||
<div className="bg-blue-500 rounded-lg p-6 text-center">
|
||||
<h3 className="text-white font-bold text-3xl mb-2">72,920</h3>
|
||||
<p className="text-white font-bold">Active students</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Hero;
|
||||
@@ -1,58 +0,0 @@
|
||||
import React from 'react'
|
||||
import { motion } from "framer-motion";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
import { CardOnlyText, CardWithButton, CardWithImage, CardWithOnlyImage, HeroSecn, } from "./Cards";
|
||||
|
||||
const ScrollReveal = ({ children, direction = "left" }) => {
|
||||
const { ref, inView } = useInView({ triggerOnce: true, threshold: 0.2 });
|
||||
|
||||
const variants = {
|
||||
left: { opacity: 0, x: -100 },
|
||||
right: { opacity: 0, x: 100 },
|
||||
up: { opacity: 0, y: 100 },
|
||||
down: { opacity: 0, y: -100 },
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
ref={ref}
|
||||
initial={variants[direction]}
|
||||
animate={inView ? { opacity: 1, x: 0, y: 0 } : {}}
|
||||
transition={{ duration: 1.2, ease: "easeOut" }}
|
||||
>
|
||||
{children}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
function Hero2() {
|
||||
const myRef = document.querySelector('.scrollable-div')
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ScrollReveal direction='up'>
|
||||
<HeroSecn />
|
||||
</ScrollReveal>
|
||||
<div className=" flex justify-center">
|
||||
<div className=" flex justify-between py-8 w-5/6 ">
|
||||
|
||||
<ScrollReveal direction='up'>
|
||||
<CardWithImage />
|
||||
</ScrollReveal>
|
||||
|
||||
<div className="flex flex-col gap-10 justify-between ">
|
||||
<ScrollReveal direction='up' > <CardOnlyText /> </ScrollReveal>
|
||||
<ScrollReveal direction='up'> <CardWithButton /> </ScrollReveal>
|
||||
</div>
|
||||
|
||||
<div className=" flex flex-col justify-between">
|
||||
<ScrollReveal direction='up'> <CardWithOnlyImage /> </ScrollReveal>
|
||||
<ScrollReveal direction='up'> <CardOnlyText /> </ScrollReveal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Hero2
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
import Navbar from "../../components/Navbar";
|
||||
import Hero from "./Hero";
|
||||
import Testimonial from "./Testimonial";
|
||||
import About from "./About";
|
||||
import Customization from "./Customization";
|
||||
import SubjectSection from "./SubjectSection";
|
||||
import ReviewSection from "./ReviewSection";
|
||||
import Footer from "./Footer";
|
||||
|
||||
const HomePage = () => {
|
||||
return (
|
||||
<>
|
||||
<Hero />
|
||||
<Testimonial />
|
||||
<About />
|
||||
<Customization />
|
||||
<SubjectSection />
|
||||
<ReviewSection />
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default HomePage;
|
||||
@@ -1,289 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const Reviews = [
|
||||
[
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
{
|
||||
src: "/images/Review1.jpeg",
|
||||
alt: "Bonnie image",
|
||||
name: "Bonnie",
|
||||
occupation: "Student",
|
||||
review:
|
||||
"As a student of this online education website, I can confidently say that it has been an incredible experience. The platform is user-friendly and making it easy for me to learn at my own pace.",
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
const ReviewSection = () => {
|
||||
return (
|
||||
<>
|
||||
<section className="bg-gray-100 py-12">
|
||||
<div className="container mx-auto">
|
||||
<div className="text-center">
|
||||
<h2 className=" text-2xl md:text-4xl font-bold mb-4">OUR TESTIMONIALS</h2>
|
||||
<h1 className="text-3xl md:text-6xl font-bold mb-4">
|
||||
What Our Students Say About Us
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="default-carousel"
|
||||
className="relative w-full"
|
||||
data-carousel="slide"
|
||||
>
|
||||
{/* <!-- Carousel wrapper --> */}
|
||||
<div className="relative h-64 overflow-hidden rounded-lg md:h-96">
|
||||
{/* <!-- Item 1 --> */}
|
||||
{Reviews.map((reviewList) => (
|
||||
<div
|
||||
className="hidden duration-700 ease-in-out w-full"
|
||||
data-carousel-item
|
||||
>
|
||||
<div className="flex w-full items-center justify-center h-full gap-8">
|
||||
{/* Review no 1 */}
|
||||
|
||||
{reviewList.map((review) => (
|
||||
<div className="w-full max-w-sm bg-white border border-gray-200 rounded-lg shadow dark:bg-gray-800 dark:border-gray-700 md:py-2">
|
||||
<div className="flex flex-col items-center pb-10 p-2">
|
||||
<img
|
||||
className="w-20 h-20 md:w-24 md:h-24 mb-3 rounded-full shadow-lg"
|
||||
src={`${review.src}`}
|
||||
alt={`${review.alt}`}
|
||||
/>
|
||||
<h5 className="mb-1 text-xl font-medium text-gray-900 dark:text-white">
|
||||
{review.name}
|
||||
</h5>
|
||||
<span className="text-base font-semibold text-gray-500 dark:text-gray-400">
|
||||
{review.occupation}
|
||||
</span>
|
||||
|
||||
<p className="md:hidden text-sm text-gray-600 text-center">
|
||||
{review.review.substring(0, 35)}....
|
||||
</p>
|
||||
|
||||
<p className="hidden md:block text-sm text-gray-600 text-center">
|
||||
{review.review.substring(0,200)}...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* <!-- Slider indicators --> */}
|
||||
<div className="absolute z-30 flex -translate-x-1/2 bottom-5 left-1/2 space-x-3 rtl:space-x-reverse">
|
||||
<button
|
||||
type="button"
|
||||
className="w-3 h-3 rounded-full"
|
||||
aria-current="true"
|
||||
aria-label="Slide 1"
|
||||
data-carousel-slide-to="0"
|
||||
></button>
|
||||
<button
|
||||
type="button"
|
||||
className="w-3 h-3 rounded-full"
|
||||
aria-current="false"
|
||||
aria-label="Slide 2"
|
||||
data-carousel-slide-to="1"
|
||||
></button>
|
||||
<button
|
||||
type="button"
|
||||
className="w-3 h-3 rounded-full"
|
||||
aria-current="false"
|
||||
aria-label="Slide 3"
|
||||
data-carousel-slide-to="2"
|
||||
></button>
|
||||
<button
|
||||
type="button"
|
||||
className="w-3 h-3 rounded-full"
|
||||
aria-current="false"
|
||||
aria-label="Slide 4"
|
||||
data-carousel-slide-to="3"
|
||||
></button>
|
||||
<button
|
||||
type="button"
|
||||
className="w-3 h-3 rounded-full"
|
||||
aria-current="false"
|
||||
aria-label="Slide 5"
|
||||
data-carousel-slide-to="4"
|
||||
></button>
|
||||
</div>
|
||||
{/* <!-- Slider controls --> */}
|
||||
<button
|
||||
type="button"
|
||||
className="absolute top-0 start-0 z-30 flex items-center justify-center h-full px-4 cursor-pointer group focus:outline-none"
|
||||
data-carousel-prev
|
||||
>
|
||||
<span className="inline-flex items-center justify-center w-10 h-10 rounded-full bg-white/30 dark:bg-gray-800/30 group-hover:bg-white/50 dark:group-hover:bg-gray-800/60 group-focus:ring-4 group-focus:ring-white dark:group-focus:ring-gray-800/70 group-focus:outline-none">
|
||||
<svg
|
||||
className="w-4 h-4 text-white dark:text-gray-800 rtl:rotate-180"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 6 10"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 1 1 5l4 4"
|
||||
/>
|
||||
</svg>
|
||||
<span className="sr-only">Previous</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="absolute top-0 end-0 z-30 flex items-center justify-center h-full px-4 cursor-pointer group focus:outline-none"
|
||||
data-carousel-next
|
||||
>
|
||||
<span className="inline-flex items-center justify-center w-10 h-10 rounded-full bg-white/30 dark:bg-gray-800/30 group-hover:bg-white/50 dark:group-hover:bg-gray-800/60 group-focus:ring-4 group-focus:ring-white dark:group-focus:ring-gray-800/70 group-focus:outline-none">
|
||||
<svg
|
||||
className="w-4 h-4 text-white dark:text-gray-800 rtl:rotate-180"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 6 10"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="m1 9 4-4-4-4"
|
||||
/>
|
||||
</svg>
|
||||
<span className="sr-only">Next</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReviewSection;
|
||||
@@ -1,179 +0,0 @@
|
||||
import React from "react";
|
||||
import { MdEngineering } from "react-icons/md";
|
||||
import { FaLaptopCode } from "react-icons/fa";
|
||||
import { LiaLanguageSolid } from "react-icons/lia";
|
||||
import { MdScience } from "react-icons/md";
|
||||
import { MdHistoryEdu } from "react-icons/md";
|
||||
import { MdPsychology } from "react-icons/md";
|
||||
import { CgWebsite } from "react-icons/cg";
|
||||
import { FaReplyAll } from "react-icons/fa";
|
||||
|
||||
const SubjectList = [
|
||||
{
|
||||
icon: "FaLaptopCode",
|
||||
title: "Programming",
|
||||
},
|
||||
{
|
||||
icon: "MdEngineering",
|
||||
title: "Engineering",
|
||||
},
|
||||
{
|
||||
icon: "LiaLanguageSolid",
|
||||
title: "Languages",
|
||||
},
|
||||
{
|
||||
icon: "MdScience",
|
||||
title: "Science",
|
||||
},
|
||||
{
|
||||
icon: "MdHistoryEdu",
|
||||
title: "History",
|
||||
},
|
||||
{
|
||||
icon: "MdPsychology",
|
||||
title: "Psychology",
|
||||
},
|
||||
{
|
||||
icon: "CgWebsite",
|
||||
title: "Web Design",
|
||||
},
|
||||
{
|
||||
icon: "FaReplyAll",
|
||||
title: "See all",
|
||||
},
|
||||
];
|
||||
const SubjectSection = () => {
|
||||
return (
|
||||
<>
|
||||
<section className="bg-white py-12 flex justify-center">
|
||||
<div className="w-11/12">
|
||||
<div className="container mx-auto">
|
||||
<div className="text-center">
|
||||
<h2 className="text-xl md:text-4xl font-bold mb-4">
|
||||
OUR TUTOR SUBJECTS
|
||||
</h2>
|
||||
<h1 className="text-4xl md:text-6xl font-bold mb-4">
|
||||
Find Online Tutor in Any Subject
|
||||
</h1>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3 md:gap-4 mt-10 md:grid-cols-3 lg:grid-cols-4">
|
||||
<div
|
||||
id="toast-success"
|
||||
className="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800 "
|
||||
role="alert"
|
||||
>
|
||||
<div className="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 md:w-9 md:h-9 text-green-500 bg-green-100 rounded-lg dark:bg-green-800 dark:text-green-200">
|
||||
<FaLaptopCode className="text-base sm:text-xl" />
|
||||
<span className="sr-only">Check icon</span>
|
||||
</div>
|
||||
<div className="ms-3 text-sm sm:text-xl font-bold text-black font-sans">
|
||||
Programming
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="toast-success"
|
||||
className="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800"
|
||||
role="alert"
|
||||
>
|
||||
<div className="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 md:w-9 md:h-9 text-blue-500 bg-blue-100 rounded-lg dark:bg-blue-800 dark:text-blue-200">
|
||||
<MdEngineering className="text-base sm:text-xl" />
|
||||
<span className="sr-only">Check icon</span>
|
||||
</div>
|
||||
<div className="ms-3 text-sm sm:text-xl font-bold text-black font-sans">
|
||||
Engineering
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="toast-success"
|
||||
className="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800"
|
||||
role="alert"
|
||||
>
|
||||
<div className="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 md:w-9 md:h-9 text-pink-500 bg-pink-100 rounded-lg dark:bg-pink-800 dark:text-pink-200">
|
||||
<LiaLanguageSolid className="text-base sm:text-xl" />
|
||||
<span className="sr-only">Check icon</span>
|
||||
</div>
|
||||
<div className="ms-3 text-base sm:text-xl font-bold text-black font-sans">
|
||||
Languages
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="toast-success"
|
||||
className="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800"
|
||||
role="alert"
|
||||
>
|
||||
<div className="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 md:w-9 md:h-9 text-purple-500 bg-purple-100 rounded-lg dark:bg-purple-800 dark:text-purple-200">
|
||||
<MdScience className="text-base sm:text-xl" />
|
||||
<span className="sr-only">Check icon</span>
|
||||
</div>
|
||||
<div className="ms-3 text-base sm:text-xl font-bold text-black font-sans">
|
||||
Science
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="toast-success"
|
||||
className="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800"
|
||||
role="alert"
|
||||
>
|
||||
<div className="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 md:w-9 md:h-9 text-yellow-500 bg-yellow-100 rounded-lg dark:bg-yellow-800 dark:text-yellow-200">
|
||||
<MdHistoryEdu className="text-base sm:text-xl" />
|
||||
<span className="sr-only">Check icon</span>
|
||||
</div>
|
||||
<div className="ms-3 text-base sm:text-xl font-bold text-black font-sans">
|
||||
History
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="toast-success"
|
||||
className="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800"
|
||||
role="alert"
|
||||
>
|
||||
<div className="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 md:w-9 md:h-9 text-red-500 bg-red-100 rounded-lg dark:bg-red-800 dark:text-red-200">
|
||||
<MdPsychology className="text-base sm:text-xl" />
|
||||
<span className="sr-only">Check icon</span>
|
||||
</div>
|
||||
<div className="ms-3 text-base sm:text-xl font-bold text-black font-sans">
|
||||
Psychology
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="toast-success"
|
||||
className="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800 md:hidden lg:flex"
|
||||
role="alert"
|
||||
>
|
||||
<div className="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 md:w-9 md:h-9 text-orange-500 bg-orange-100 rounded-lg dark:bg-orange-800 dark:text-orange-200 ">
|
||||
<CgWebsite className="text-base sm:text-xl" />
|
||||
<span className="sr-only">Check icon</span>
|
||||
</div>
|
||||
<div className="ms-3 text-base sm:text-xl font-bold text-black font-sans">
|
||||
Web Design
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="toast-success"
|
||||
className="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800 md:hidden lg:flex"
|
||||
role="alert"
|
||||
>
|
||||
<div className="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 md:w-9 md:h-9 text-gray-500 bg-gray-100 rounded-lg dark:bg-gray-800 dark:text-gray-200">
|
||||
<FaReplyAll className="text-base sm:text-xl" />
|
||||
<span class="sr-only">Check icon</span>
|
||||
</div>
|
||||
<div className="ms-3 text-base sm:text-xl font-bold text-black font-sans">
|
||||
See all
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SubjectSection;
|
||||
@@ -1,87 +0,0 @@
|
||||
import React from "react";
|
||||
import { IoMdContacts } from "react-icons/io";
|
||||
import { FaClock } from "react-icons/fa";
|
||||
import { FaMessage } from "react-icons/fa6";
|
||||
|
||||
const Testimonial = () => {
|
||||
return (
|
||||
<>
|
||||
<section className="bg-gray-100 py-12 px-2 md:px-32">
|
||||
<div className="container mx-auto">
|
||||
<div className="text-center">
|
||||
<h2 className="text-xl sm:text-4xl font-bold mb-4">WHY CHOOSE US</h2>
|
||||
<h1 className="text-3xl sm:text-6xl font-bold mb-4">
|
||||
Benefits of online tutoring services with us
|
||||
</h1>
|
||||
</div>
|
||||
<div className="flex flex-col sm:flex-row justify-center mt-8 h-auto">
|
||||
<div className="w-full h-full md:w-1/3 p-4">
|
||||
<div className="bg-white rounded-lg p-6 text-start shadow-md flex flex-col gap-2">
|
||||
<IoMdContacts className=" text-4xl p-1 rounded-lg text-white bg-blue-600 " />
|
||||
|
||||
<h3 className="text-xl font-bold mb-2">One-on-One Mentoring</h3>
|
||||
<p className="text-gray-600 text-sm">
|
||||
All of our special education experts have a degree in special
|
||||
education
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full h-full md:w-1/3 p-4">
|
||||
<div className="bg-white rounded-lg p-6 text-start shadow-md flex flex-col gap-2">
|
||||
<FaClock className=" text-4xl p-1.5 rounded-lg text-white bg-green-600 " />
|
||||
|
||||
<h3 className="text-xl font-bold mb-2">24/7 Mentor Availability</h3>
|
||||
<p className="text-gray-600 text-sm">
|
||||
Our Mentors are always available to respond as quick as
|
||||
possible for you
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full h-full md:w-1/3 p-4">
|
||||
<div className="bg-white rounded-lg p-6 text-start shadow-md flex flex-col gap-2">
|
||||
<FaMessage className=" text-4xl p-2 rounded-lg text-white bg-orange-600 " />
|
||||
|
||||
<h3 className="text-xl font-bold mb-2">Interactive Session</h3>
|
||||
<p className="text-gray-600 text-sm">
|
||||
Our digital messaging with audio and video chat features give interactiveness.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <div class="w-full md:w-1/3 p-4">
|
||||
<div class="bg-white rounded-lg p-6 text-center shadow-md">
|
||||
<img
|
||||
src="https://cdn-icons-png.flaticon.com/512/2768/2768851.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 mb-4"
|
||||
/>
|
||||
<h3 class="text-2xl font-bold mb-2">Interactive Whiteboard</h3>
|
||||
<p class="text-gray-600">
|
||||
Our digital whiteboard equipped with audio and video chat
|
||||
features
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full md:w-1/3 p-4">
|
||||
<div class="bg-white rounded-lg p-6 text-center shadow-md">
|
||||
<img
|
||||
src="https://cdn-icons-png.flaticon.com/512/2768/2768851.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 mb-4"
|
||||
/>
|
||||
<h3 class="text-2xl font-bold mb-2">Affordable Prices</h3>
|
||||
<p class="text-gray-600">
|
||||
Choose an expert tutor based on your budget and per hour
|
||||
</p>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Testimonial;
|
||||
@@ -1,147 +0,0 @@
|
||||
import React, { useRef } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { userSliceActions } from "../../store/userSlice";
|
||||
import { BACKEND_URL } from "../../constants";
|
||||
|
||||
const LoginPage = () => {
|
||||
const emailElement = useRef();
|
||||
const passwordElement = useRef();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleLogin = async (event) => {
|
||||
event.preventDefault();
|
||||
const responce = await fetch(`${BACKEND_URL}/api/v1/login`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: emailElement.current.value,
|
||||
password: passwordElement.current.value,
|
||||
}),
|
||||
});
|
||||
|
||||
const user = await responce.json();
|
||||
|
||||
//console.log("User Login Data is here : ", user);
|
||||
|
||||
dispatch(userSliceActions.addUser(user.data));
|
||||
|
||||
emailElement.current.value = "";
|
||||
passwordElement.current.value = "";
|
||||
|
||||
if (user.success == true) {
|
||||
navigate("/");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<section className="bg-gray-100 font-sans h-[91vh] flex flex-col justify-center md:p-5">
|
||||
<div className="container mx-auto p-4 ">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<div className="bg-gradient-to-br from-purple-300 to-pink-200 overflow-hidden rounded-lg shadow-md min-h-40 object-center">
|
||||
<div className="flex flex-col items-center justify-center h-full relative">
|
||||
<img
|
||||
src="/images/background1.jpg"
|
||||
alt=""
|
||||
className="absolute order-3 w-full h-full"
|
||||
/>
|
||||
<h1 className="text-6xl font-bold text-white mb-4 md:text-6xl lg:text-9xl relative ml-8">
|
||||
Welcome Back!
|
||||
</h1>
|
||||
{/* <img src="/images/background.jpg" alt="" className="absolute order-3"/> */}
|
||||
{/* <img
|
||||
src="https://cdn.pixabay.com/photo/2017/02/21/15/19/arrow-2074591_960_720.png"
|
||||
alt="Arrow"
|
||||
className="w-16 h-16 text-white"
|
||||
/> */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-white p-8 rounded-lg shadow-md h-full lg:p-36">
|
||||
<h1 className="text-2xl font-bold text-gray-800 mb-4">Login</h1>
|
||||
<p className="text-gray-600 mb-6">
|
||||
Welcome back! Please login to your account.
|
||||
</p>
|
||||
<form className="space-y-6" onSubmit={handleLogin}>
|
||||
<div>
|
||||
<label
|
||||
for="username"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="username"
|
||||
ref={emailElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="username@gmail.com"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
for="password"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
ref={passwordElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="********"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<input
|
||||
id="remember_me"
|
||||
type="checkbox"
|
||||
value=""
|
||||
className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
/>
|
||||
<label
|
||||
for="remember_me"
|
||||
className="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300"
|
||||
>
|
||||
Remember Me
|
||||
</label>
|
||||
</div>
|
||||
<Link
|
||||
to={"/user/forgetpassword"}
|
||||
className="text-sm font-medium text-blue-600 hover:underline dark:text-blue-500"
|
||||
>
|
||||
Forget Password?
|
||||
</Link>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="text-white bg-purple-500 hover:bg-purple-700 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
<p className="text-gray-600 text-center mt-4">
|
||||
New User?{" "}
|
||||
<Link
|
||||
to={"/user/signup"}
|
||||
className="text-blue-600 hover:underline"
|
||||
>
|
||||
Signup
|
||||
</Link>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginPage;
|
||||
@@ -1,16 +0,0 @@
|
||||
import React from "react";
|
||||
import Navbar from "../../components/Navbar.jsx";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import Container from "../../components/Container.jsx";
|
||||
|
||||
const MainLoginPage = () => {
|
||||
return (
|
||||
<>
|
||||
<Container>
|
||||
<Outlet />
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default MainLoginPage;
|
||||
@@ -1,233 +0,0 @@
|
||||
import React, { useRef } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { BACKEND_URL } from "../../constants";
|
||||
|
||||
const SignupPage = () => {
|
||||
const firstNameElement = useRef();
|
||||
const lastNameElement = useRef();
|
||||
const emailElement = useRef();
|
||||
const roleElement = useRef();
|
||||
const passwordElement = useRef();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleRegisteration = async (event) => {
|
||||
event.preventDefault();
|
||||
let userRole;
|
||||
if (roleElement.current.value == "Student") {
|
||||
userRole = "user";
|
||||
} else {
|
||||
userRole = "mentor";
|
||||
}
|
||||
const user = {
|
||||
name:
|
||||
firstNameElement.current.value + " " + lastNameElement.current.value,
|
||||
email: emailElement.current.value,
|
||||
password: passwordElement.current.value,
|
||||
role: userRole,
|
||||
};
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
const responce = await fetch(`${BACKEND_URL}/api/v1/register`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(user),
|
||||
credentials: "include",
|
||||
});
|
||||
const data = await responce.json();
|
||||
|
||||
//console.log("Our user data is : ", data);
|
||||
|
||||
firstNameElement.current.value = "";
|
||||
lastNameElement.current.value = "";
|
||||
emailElement.current.value = "";
|
||||
passwordElement.current.value = "";
|
||||
roleElement.current.value = "";
|
||||
|
||||
if (data.success == true) {
|
||||
navigate("/user/login");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="bg-gray-100 font-sans h-[91vh] flex flex-col justify-center md:p-5 ">
|
||||
<div className="container mx-auto p-4 mt-64 sm:mt-32 md:mt-0">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<div className="bg-gradient-to-br from-purple-300 to-pink-200 overflow-hidden rounded-lg shadow-md min-h-40 object-center md:hidden">
|
||||
<div className="flex flex-col items-center justify-center h-full relative">
|
||||
<img
|
||||
src="/images/background1.jpg"
|
||||
alt=""
|
||||
className="absolute order-3 w-full h-full"
|
||||
/>
|
||||
<h1 className="text-6xl font-bold text-white mb-4 md:text-6xl lg:text-9xl relative ml-8">
|
||||
Welcome to MentorFlux!
|
||||
</h1>
|
||||
{/* <img src="./images/background.jpg" alt="" className="absolute order-3"/> */}
|
||||
{/* <img
|
||||
src="https://cdn.pixabay.com/photo/2017/02/21/15/19/arrow-2074591_960_720.png"
|
||||
alt="Arrow"
|
||||
className="w-16 h-16 text-white"
|
||||
/> */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-white p-8 rounded-lg shadow-md h-full lg:p-16">
|
||||
<h1 className="text-2xl font-bold text-gray-800 mb-4">
|
||||
Register Your account
|
||||
</h1>
|
||||
<p className="text-gray-600 mb-6">
|
||||
Welcome to MentorFlux. Please register your new account.
|
||||
</p>
|
||||
<form
|
||||
action="#"
|
||||
className="space-y-6"
|
||||
onSubmit={handleRegisteration}
|
||||
>
|
||||
<div className="flex flex-col gap-5 sm:flex-row">
|
||||
<div className="w-full">
|
||||
<label
|
||||
htmlFor="username"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
First Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="firstName"
|
||||
ref={firstNameElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Enter your First name here..."
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<label
|
||||
htmlFor="username"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Last Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="LastName"
|
||||
ref={lastNameElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Enter your Last name here..."
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
htmlFor="username"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
ref={emailElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Please Enter your Email here..."
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<label
|
||||
htmlFor="countries"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Select your Role
|
||||
</label>
|
||||
<select
|
||||
id="role"
|
||||
ref={roleElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
>
|
||||
<option>Student</option>
|
||||
<option>Mentor</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="password"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
ref={passwordElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Please enter password having at least 6 unique letters.. "
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<input
|
||||
id="remember_me"
|
||||
type="checkbox"
|
||||
value=""
|
||||
className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
/>
|
||||
<label
|
||||
htmlFor="remember_me"
|
||||
className="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300"
|
||||
>
|
||||
Remember Me
|
||||
</label>
|
||||
</div>
|
||||
<a
|
||||
href="#"
|
||||
className="text-sm font-medium text-blue-600 hover:underline dark:text-blue-500"
|
||||
></a>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="text-white bg-purple-500 hover:bg-purple-700 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||
>
|
||||
Register your Account
|
||||
</button>
|
||||
<p className="text-gray-600 text-center mt-4">
|
||||
Already have an Account ?{" "}
|
||||
<Link
|
||||
to={"/user/login"}
|
||||
className="text-blue-600 hover:underline"
|
||||
>
|
||||
Login
|
||||
</Link>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
<div className="bg-gradient-to-br from-purple-300 to-pink-200 overflow-hidden rounded-lg shadow-md min-h-40 object-center hidden md:block">
|
||||
<div className="flex flex-col items-center justify-center h-full relative text-center">
|
||||
<img
|
||||
src="/images/background1.jpg"
|
||||
alt=""
|
||||
className="absolute order-3 w-full h-full"
|
||||
/>
|
||||
<h1 className="text-5xl font-bold text-white mb-4 md:text-5xl lg:text-8xl relative ml-8 text-center">
|
||||
Welcome to MentorFlux!
|
||||
</h1>
|
||||
{/* <img src="./images/background.jpg" alt="" className="absolute order-3"/> */}
|
||||
{/* <img
|
||||
src="https://cdn.pixabay.com/photo/2017/02/21/15/19/arrow-2074591_960_720.png"
|
||||
alt="Arrow"
|
||||
className="w-16 h-16 text-white"
|
||||
/> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignupPage;
|
||||
@@ -1,77 +0,0 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import { IoIosKey } from "react-icons/io";
|
||||
import { Link } from "react-router-dom";
|
||||
import { FaArrowLeft } from "react-icons/fa6";
|
||||
import { BACKEND_URL } from "../../constants";
|
||||
|
||||
const ForgetPassword = () => {
|
||||
const emailElement = useRef();
|
||||
|
||||
const [status, setStatus] = useState(false);
|
||||
|
||||
const handleForgetPassword = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const responce = await fetch(`${BACKEND_URL}/api/v1//password/forgot`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: emailElement.current.value,
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await responce.json();
|
||||
|
||||
if (data.success === true) {
|
||||
setStatus(true);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="w-full h-[78vh] flex justify-center items-center">
|
||||
<div className="">
|
||||
<div className="flex flex-col items-center gap-12">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<IoIosKey className="text-5xl bg-purple-200 p-2 rounded-full text-purple-500" />
|
||||
<h2 className="text-3xl font-bold font-sans">Forget Password?</h2>
|
||||
<p className="text-gray-500">
|
||||
No worries, we'll send you resent instructions.
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
className="flex flex-col w-full gap-5"
|
||||
onSubmit={handleForgetPassword}
|
||||
>
|
||||
<div>
|
||||
<label htmlFor="email"></label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
placeholder="Enter your email"
|
||||
className="w-full rounded-md border-gray-400 border-2"
|
||||
ref={emailElement}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="focus:outline-none text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg text-base px-5 py-2.5 mb-2 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-900"
|
||||
>
|
||||
{status === false ? "Send Email" : "Email Sent to your Mail"}
|
||||
</button>
|
||||
|
||||
<Link
|
||||
to={"/user/login"}
|
||||
className="text-center text-gray-600 inline-flex items-center justify-center gap-2"
|
||||
>
|
||||
<FaArrowLeft className="text-lg" /> Back to Login Page
|
||||
</Link>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForgetPassword;
|
||||
@@ -1,131 +0,0 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import { RiLockPasswordFill } from "react-icons/ri";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
import { FaArrowLeft } from "react-icons/fa6";
|
||||
import { BACKEND_URL } from "../../constants";
|
||||
|
||||
const ResetPassword = () => {
|
||||
const [secure, setSecure] = useState(true);
|
||||
|
||||
const newPassworElement = useRef();
|
||||
const confirmPassworElement = useRef();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { token } = useParams();
|
||||
|
||||
// console.log("So our Token is : ", token);
|
||||
|
||||
const handleResetPassword = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (
|
||||
confirmPassworElement.current.value !== newPassworElement.current.value
|
||||
) {
|
||||
setSecure(false);
|
||||
} else {
|
||||
const responce = await fetch(
|
||||
`${BACKEND_URL}/api/v1/password/reset/${token}`,
|
||||
{
|
||||
method: "PUT",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
password: newPassworElement.current.value,
|
||||
confirmPassword: confirmPassworElement.current.value,
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
const data = await responce.json();
|
||||
|
||||
//console.log("Status of the Reset password", data);
|
||||
|
||||
if (data.success === true) {
|
||||
navigate("/user/login");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full h-[78vh] flex justify-center items-center">
|
||||
<div className="">
|
||||
<div className="flex flex-col items-center gap-10">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<RiLockPasswordFill className="text-5xl bg-purple-200 p-2 rounded-full text-purple-500" />
|
||||
<h2 className="text-3xl font-bold font-sans">
|
||||
Create New Password
|
||||
</h2>
|
||||
<p className="text-gray-500">
|
||||
Create your new, unique and secure password here.
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
className="flex flex-col w-full gap-5"
|
||||
onSubmit={handleResetPassword}
|
||||
>
|
||||
<div className="flex flex-col gap-2">
|
||||
<label
|
||||
htmlFor="passwordNew"
|
||||
className="text-gray-500 font-semibold"
|
||||
>
|
||||
New Password :
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
id="passwordNew"
|
||||
ref={newPassworElement}
|
||||
placeholder="Enter your New Password"
|
||||
className="w-full rounded-md border-gray-400 border-2"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<label
|
||||
htmlFor="passwordConfirm"
|
||||
className="text-gray-500 font-semibold"
|
||||
>
|
||||
Confirm Password :
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
id="passwordConfirm"
|
||||
ref={confirmPassworElement}
|
||||
placeholder="Enter your Confirm Password"
|
||||
className="w-full rounded-md border-gray-400 border-2"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p
|
||||
className={`text-red-800 text-sm underline w-96 text-center ${
|
||||
secure && "hidden"
|
||||
} `}
|
||||
>
|
||||
Password and confirm Password is not same.Please Enter new
|
||||
password and confirm Password same
|
||||
</p>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="focus:outline-none text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg text-base px-5 py-2.5 mb-2 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-900"
|
||||
>
|
||||
Reset Password
|
||||
</button>
|
||||
|
||||
<Link
|
||||
to={"/user/login"}
|
||||
className="text-center text-gray-600 inline-flex items-center justify-center gap-2"
|
||||
>
|
||||
<FaArrowLeft className="text-lg" /> Back to Login Page
|
||||
</Link>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResetPassword;
|
||||
@@ -1,202 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const Dashboard = () => {
|
||||
return (
|
||||
<>
|
||||
|
||||
<div className="w-full bg-white rounded-lg shadow p-4">
|
||||
<div className="flex flex-col justify-center items-center mb-4">
|
||||
<h2 className="text-2xl font-bold font-sans border-b-2 py-2">
|
||||
Upcoming Sessions{" "}
|
||||
</h2>
|
||||
<div className="bg-gray-300 w-full h-52 rounded-lg"></div>
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<h3 className="text-lg font-medium">Recent Activity</h3>
|
||||
<p className="text-gray-500 text-sm mt-2">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
</p>
|
||||
<div className="grid grid-cols-1 gap-4 mt-4">
|
||||
<input type="range" className="w-full h-auto" readOnly:true/>
|
||||
<div className="bg-gray-100 rounded-lg p-4 flex justify-between items-center">
|
||||
|
||||
<div className="flex items-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-6 w-6 text-green-500"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M13 7l5 5m0 0l-5 5m5-5H6"
|
||||
/>
|
||||
</svg>
|
||||
<span className="ml-2 font-medium">Topup</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-gray-500 text-sm">06:24:45 AM</span>
|
||||
<span className="ml-2 text-green-500 text-sm">+$5,553</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-lg font-medium">Weekly Summary</h3>
|
||||
<div className="grid grid-cols-8 gap-2 mt-4">
|
||||
<div className="col-span-1 flex flex-col justify-between items-center bg-gray-100 rounded-lg p-2">
|
||||
<span className="text-gray-500 text-xs">Sun</span>
|
||||
</div>
|
||||
<div className="col-span-1 flex flex-col justify-between items-center bg-gray-100 rounded-lg p-2">
|
||||
<span className="text-gray-500 text-xs">Mon</span>
|
||||
</div>
|
||||
<div className="col-span-1 flex flex-col justify-between items-center bg-gray-100 rounded-lg p-2">
|
||||
<span className="text-gray-500 text-xs">Tue</span>
|
||||
</div>
|
||||
<div className="col-span-1 flex flex-col justify-between items-center bg-gray-100 rounded-lg p-2">
|
||||
<span className="text-gray-500 text-xs">Wed</span>
|
||||
</div>
|
||||
<div className="col-span-1 flex flex-col justify-between items-center bg-gray-100 rounded-lg p-2">
|
||||
<span className="text-gray-500 text-xs">Thu</span>
|
||||
</div>
|
||||
<div className="col-span-1 flex flex-col justify-between items-center bg-gray-100 rounded-lg p-2">
|
||||
<span className="text-gray-500 text-xs">Fri</span>
|
||||
</div>
|
||||
<div className="col-span-1 flex flex-col justify-between items-center bg-gray-100 rounded-lg p-2">
|
||||
<span className="text-gray-500 text-xs">Sat</span>
|
||||
</div>
|
||||
<div className="col-span-1 flex flex-col justify-between items-center bg-gray-100 rounded-lg p-2">
|
||||
<span className="text-gray-500 text-xs">Completed</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-8 gap-2 mt-2">
|
||||
<div
|
||||
className="col-span-1 flex flex-col justify-between items-center rounded-lg p-2"
|
||||
style={{ height: "100px" }}
|
||||
>
|
||||
<div className="bg-green-500 rounded-t-lg h-16"></div>
|
||||
<div className="bg-gray-300 h-4"></div>
|
||||
<div className="bg-red-500 rounded-b-lg h-16"></div>
|
||||
</div>
|
||||
<div
|
||||
className="col-span-1 flex flex-col justify-between items-center rounded-lg p-2"
|
||||
style={{ height: "100px" }}
|
||||
>
|
||||
<div className="bg-green-500 rounded-t-lg h-20"></div>
|
||||
<div className="bg-gray-300 h-8"></div>
|
||||
<div className="bg-red-500 rounded-b-lg h-12"></div>
|
||||
</div>
|
||||
<div
|
||||
className="col-span-1 flex flex-col justify-between items-center rounded-lg p-2"
|
||||
style={{ height: "100px" }}
|
||||
>
|
||||
<div className="bg-green-500 rounded-t-lg h-12"></div>
|
||||
<div className="bg-gray-300 h-12"></div>
|
||||
<div className="bg-red-500 rounded-b-lg h-20"></div>
|
||||
</div>
|
||||
<div
|
||||
className="col-span-1 flex flex-col justify-between items-center rounded-lg p-2"
|
||||
style={{ height: "100px" }}
|
||||
>
|
||||
<div className="bg-green-500 rounded-t-lg h-24"></div>
|
||||
<div className="bg-gray-300 h-4"></div>
|
||||
<div className="bg-red-500 rounded-b-lg h-8"></div>
|
||||
</div>
|
||||
<div
|
||||
className="col-span-1 flex flex-col justify-between items-center rounded-lg p-2"
|
||||
style={{ height: "100px" }}
|
||||
>
|
||||
<div className="bg-green-500 rounded-t-lg h-16"></div>
|
||||
<div className="bg-gray-300 h-12"></div>
|
||||
<div className="bg-red-500 rounded-b-lg h-16"></div>
|
||||
</div>
|
||||
<div
|
||||
className="col-span-1 flex flex-col justify-between items-center rounded-lg p-2"
|
||||
style={{ height: "100px" }}
|
||||
>
|
||||
<div className="bg-green-500 rounded-t-lg h-16"></div>
|
||||
<div className="bg-gray-300 h-4"></div>
|
||||
<div className="bg-red-500 rounded-b-lg h-24"></div>
|
||||
</div>
|
||||
<div
|
||||
className="col-span-1 flex flex-col justify-between items-center rounded-lg p-2"
|
||||
style={{ height: "100px" }}
|
||||
>
|
||||
<div className="bg-green-500 rounded-t-lg h-8"></div>
|
||||
<div className="bg-gray-300 h-16"></div>
|
||||
<div className="bg-red-500 rounded-b-lg h-20"></div>
|
||||
</div>
|
||||
<div
|
||||
className="col-span-1 flex flex-col justify-between items-center rounded-lg p-2"
|
||||
style={{ height: "100px" }}
|
||||
>
|
||||
<div className="bg-gray-300 h-24"></div>
|
||||
<div className="bg-gray-300 h-24"></div>
|
||||
<div className="bg-gray-300 h-24"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-lg font-medium">Notifications</h3>
|
||||
<div className="grid grid-cols-1 gap-4 mt-4">
|
||||
<div className="bg-gray-100 rounded-lg p-4 flex justify-between items-center">
|
||||
<div className="flex items-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-6 w-6 text-green-500"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M13 7l5 5m0 0l-5 5m5-5H6"
|
||||
/>
|
||||
</svg>
|
||||
<span className="ml-2 font-medium">Topup</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-gray-500 text-sm">06:24:45 AM</span>
|
||||
<span className="ml-2 text-green-500 text-sm">+$5,553</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 mt-4">
|
||||
<div className="bg-gray-100 rounded-lg p-4 flex justify-between items-center">
|
||||
<div className="flex items-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-6 w-6 text-green-500"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M13 7l5 5m0 0l-5 5m5-5H6"
|
||||
/>
|
||||
</svg>
|
||||
<span className="ml-2 font-medium">Topup</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-gray-500 text-sm">06:24:45 AM</span>
|
||||
<span className="ml-2 text-green-500 text-sm">+$5,553</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Dashboard;
|
||||
@@ -1,67 +0,0 @@
|
||||
import { useEffect } from "react";
|
||||
|
||||
const AddCrop = () => {
|
||||
return (
|
||||
<>
|
||||
{" "}
|
||||
<form onSubmit={handleAvatar}>
|
||||
<div className="flex items-center justify-center w-full">
|
||||
<img src={formData.avatar && `${formData.avatar}`} alt="" />
|
||||
<label
|
||||
for="dropzone-file"
|
||||
className="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600"
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center pt-5 pb-6 ">
|
||||
<svg
|
||||
className="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 20 16"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2"
|
||||
/>
|
||||
</svg>
|
||||
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
{avatar ? (
|
||||
<span className="font-semibold">
|
||||
Avatar uploaded successfulky
|
||||
</span>
|
||||
) : (
|
||||
<span className="font-semibold">
|
||||
Click to upload and press Upload button
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
SVG, PNG, JPG or GIF (MAX. 800x400px)
|
||||
</p>
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-gray-600 px-4 py-1 rounded-lg text-white font-semibold my-4"
|
||||
>
|
||||
Upload
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
id="dropzone-file"
|
||||
type="file"
|
||||
className="hidden"
|
||||
onChange={(e) => {
|
||||
setAvatar(e.target.files[0]);
|
||||
//console.log(e.target.files[0]);
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddCrop;
|
||||
@@ -1,250 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const AddFarm = () => {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [farmName, setFarmName] = useState("");
|
||||
const [location, setLocation] = useState("");
|
||||
const [waterContent, setWaterContent] = useState("");
|
||||
const [sizeContent, setSizeContent] = useState("");
|
||||
const [soilType, setSoilType] = useState("");
|
||||
const [error, setError] = useState(null);
|
||||
const [success, setSuccess] = useState(false);
|
||||
const navigator = useNavigate();
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
const farmData = {
|
||||
name: farmName,
|
||||
location,
|
||||
waterContent,
|
||||
soilType,
|
||||
size: sizeContent,
|
||||
};
|
||||
|
||||
console.log(farmData);
|
||||
|
||||
try {
|
||||
const response = await fetch("http://localhost:8000/api/v1/farm", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(farmData),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add farm");
|
||||
}
|
||||
|
||||
navigator("farmpage");
|
||||
setSuccess(true);
|
||||
setError(null);
|
||||
setIsModalOpen(false);
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
setSuccess(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
className="block text-white bg-green-600 hover:bg-green-700 focus:ring-4 focus:outline-none focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center"
|
||||
type="button"
|
||||
>
|
||||
Add New Farm
|
||||
</button>
|
||||
|
||||
{isModalOpen && (
|
||||
<div className="fixed inset-0 z-50 overflow-y-auto overflow-x-hidden flex items-center justify-center">
|
||||
<div
|
||||
className="fixed inset-0 bg-black bg-opacity-50 transition-opacity"
|
||||
onClick={() => setIsModalOpen(false)}
|
||||
></div>
|
||||
|
||||
<div className="relative w-full max-w-2xl mx-4">
|
||||
<div className="relative bg-white rounded-xl shadow-lg">
|
||||
{/* Decorative Leaves */}
|
||||
<div className="absolute right-0 top-0 h-full w-48 overflow-hidden pointer-events-none">
|
||||
<svg
|
||||
viewBox="0 0 200 800"
|
||||
className="absolute right-0 h-full transform translate-x-16 fill-green-100"
|
||||
>
|
||||
<path d="M0,0 Q100,200 0,400 Q100,600 0,800 L200,800 L200,0 Z" />
|
||||
</svg>
|
||||
<svg
|
||||
viewBox="0 0 200 800"
|
||||
className="absolute right-0 h-full transform translate-x-8 fill-green-200/40"
|
||||
>
|
||||
<path d="M0,0 Q80,200 0,400 Q80,600 0,800 L200,800 L200,0 Z" />
|
||||
</svg>
|
||||
|
||||
<svg
|
||||
viewBox="0 0 100 100"
|
||||
className="absolute right-12 top-20 w-16 h-16 fill-green-300/30"
|
||||
>
|
||||
<path d="M50,0 Q100,50 50,100 Q0,50 50,0 Z" />
|
||||
</svg>
|
||||
<svg
|
||||
viewBox="0 0 100 100"
|
||||
className="absolute right-16 top-48 w-12 h-12 fill-green-400/20"
|
||||
>
|
||||
<path d="M50,0 Q100,50 50,100 Q0,50 50,0 Z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* Modal Header */}
|
||||
<div className="flex items-center justify-between p-4 md:p-5 border-b rounded-t border-gray-200">
|
||||
<h3 className="text-2xl font-semibold text-gray-800">
|
||||
Add New Farm
|
||||
</h3>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIsModalOpen(false)}
|
||||
className="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 inline-flex justify-center items-center"
|
||||
>
|
||||
<svg
|
||||
className="w-3 h-3"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 14 14"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"
|
||||
/>
|
||||
</svg>
|
||||
<span className="sr-only">Close modal</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Modal Body */}
|
||||
<div className="p-4 md:p-5">
|
||||
<form className="space-y-4" onSubmit={handleSubmit}>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="farmName"
|
||||
className="block text-sm font-semibold text-gray-700 mb-2"
|
||||
>
|
||||
Farm Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="farmName"
|
||||
value={farmName}
|
||||
onChange={(e) => setFarmName(e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:ring-2 focus:ring-green-400 focus:border-transparent transition duration-200 ease-in-out bg-white/80"
|
||||
placeholder="Enter farm name"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
htmlFor="location"
|
||||
className="block text-sm font-semibold text-gray-700 mb-2"
|
||||
>
|
||||
Location
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="location"
|
||||
value={location}
|
||||
onChange={(e) => setLocation(e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:ring-2 focus:ring-green-400 focus:border-transparent transition duration-200 ease-in-out bg-white/80"
|
||||
placeholder="Enter location"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
htmlFor="waterContent"
|
||||
className="block text-sm font-semibold text-gray-700 mb-2"
|
||||
>
|
||||
Water Content
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="waterContent"
|
||||
value={waterContent}
|
||||
onChange={(e) => setWaterContent(e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:ring-2 focus:ring-green-400 focus:border-transparent transition duration-200 ease-in-out bg-white/80"
|
||||
placeholder="Enter water content"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
htmlFor="waterContent"
|
||||
className="block text-sm font-semibold text-gray-700 mb-2"
|
||||
>
|
||||
Size of Land
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="waterContent"
|
||||
value={sizeContent}
|
||||
onChange={(e) => setSizeContent(e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:ring-2 focus:ring-green-400 focus:border-transparent transition duration-200 ease-in-out bg-white/80"
|
||||
placeholder="Enter water content"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
htmlFor="soilType"
|
||||
className="block text-sm font-semibold text-gray-700 mb-2"
|
||||
>
|
||||
Soil Type
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="soilType"
|
||||
value={soilType}
|
||||
onChange={(e) => setSoilType(e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:ring-2 focus:ring-green-400 focus:border-transparent transition duration-200 ease-in-out bg-white/80"
|
||||
placeholder="Enter soil type"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full bg-green-600 hover:bg-green-700 text-white font-semibold py-3 px-6 rounded-lg transition duration-200 ease-in-out transform hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-green-400 focus:ring-offset-2"
|
||||
>
|
||||
Add Farm
|
||||
</button>
|
||||
|
||||
{error && (
|
||||
<p className="mt-4 text-red-500 text-sm bg-red-50 p-3 rounded-lg">
|
||||
{error}
|
||||
</p>
|
||||
)}
|
||||
{success && (
|
||||
<p className="mt-4 text-green-500 text-sm bg-green-50 p-3 rounded-lg">
|
||||
Farm added successfully!
|
||||
</p>
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddFarm;
|
||||
@@ -1,61 +0,0 @@
|
||||
const Farm = ({ farmData }) => {
|
||||
return (
|
||||
<div className="w-full ">
|
||||
<h1 className="text-2xl font-bold mb-4">{farmData.name}</h1>
|
||||
|
||||
<table className="min-w-full text-left">
|
||||
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Farm Name
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Location
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Type
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Size (acres)
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Water Content
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3">
|
||||
Action
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="odd:bg-white even:bg-gray-50 dark:odd:bg-gray-900 dark:even:bg-gray-800 border-b dark:border-gray-700">
|
||||
{/* Clicking on the name cell can navigate to a more detailed view if needed */}
|
||||
<td
|
||||
className="px-6 py-4 cursor-pointer hover:text-blue-600 transition"
|
||||
onClick={() => {
|
||||
// Navigate to a detailed view for this farm if desired
|
||||
navigate(`farmpage/${farmData._id}`);
|
||||
}}
|
||||
>
|
||||
{farmData.name}
|
||||
</td>
|
||||
<td className="px-6 py-4">{farmData.location}</td>
|
||||
<td className="px-6 py-4">{farmData.soilType}</td>
|
||||
<td className="px-6 py-4">{farmData.size}</td>
|
||||
<td className="px-6 py-4">{farmData.waterContent}</td>
|
||||
<td className="px-6 py-4">
|
||||
<button
|
||||
onClick={() =>
|
||||
navigate(`/user/dashboard/updatefarm?farmId=${farmData._id}`)
|
||||
}
|
||||
className="font-medium text-blue-600 dark:text-blue-500 hover:underline"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default Farm;
|
||||
@@ -1,60 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useParams, useNavigate } from "react-router-dom";
|
||||
import Farm from "./Farm";
|
||||
import AddCrop from "./AddCrop";
|
||||
|
||||
export default function FarmPage() {
|
||||
const { farmId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const [farmData, setFarmData] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetching() {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`http://localhost:8000/api/v1/farm/${farmId}`,
|
||||
{
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
const jsonData = await response.json();
|
||||
console.log(jsonData);
|
||||
setFarmData(jsonData);
|
||||
} catch (error) {
|
||||
console.error("Error fetching farm data: ", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
fetching();
|
||||
}, [farmId]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="w-full bg-white rounded-lg shadow p-4">
|
||||
<p>Loading farm data...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!farmData) {
|
||||
return (
|
||||
<div className="w-full bg-white rounded-lg shadow p-4">
|
||||
<p>No farm data found.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full bg-white rounded-lg shadow p-4">
|
||||
{/* Back Button */}
|
||||
<Farm farmData={farmData}></Farm>
|
||||
<AddCrop></AddCrop>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const UpdateFarm = () => {
|
||||
const [farmName, setFarmName] = useState("");
|
||||
const [location, setLocation] = useState("");
|
||||
const [waterContent, setWaterContent] = useState("");
|
||||
const [soilType, setSoilType] = useState("");
|
||||
const [sizeContent, setSizeContent] = useState("");
|
||||
const [error, setError] = useState(null);
|
||||
const [success, setSuccess] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
const farmData = {
|
||||
name: farmName,
|
||||
location,
|
||||
waterContent,
|
||||
soilType,
|
||||
size: sizeContent,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
"http://localhost:8000/api/v1/farm/67b9b3a1b68365aa35ae0e5f",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(farmData),
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to Update the farm");
|
||||
}
|
||||
|
||||
setSuccess(true);
|
||||
setError(null);
|
||||
// navigate to the dashboard:
|
||||
navigate("/dashboard");
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
setSuccess(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full bg-white rounded-lg shadow p-4">
|
||||
<h1 className="w-full text-center text-2xl font-bold my-5">
|
||||
Update farm
|
||||
</h1>
|
||||
|
||||
<div className="mb-4 flex justify-end space-x-4">
|
||||
<form className="max-w-md mx-auto w-80" onSubmit={handleSubmit}>
|
||||
<div className="mb-5">
|
||||
<label
|
||||
htmlFor="farmName"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Farm Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="farmName"
|
||||
value={farmName}
|
||||
onChange={(e) => setFarmName(e.target.value)}
|
||||
className="shadow-xs bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-5">
|
||||
<label
|
||||
htmlFor="location"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Location
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="location"
|
||||
value={location}
|
||||
onChange={(e) => setLocation(e.target.value)}
|
||||
className="shadow-xs bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-5">
|
||||
<label
|
||||
htmlFor="waterContent"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Water Content
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="waterContent"
|
||||
value={waterContent}
|
||||
onChange={(e) => setWaterContent(e.target.value)}
|
||||
className="shadow-xs bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-5">
|
||||
<label
|
||||
htmlFor="soilType"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Soil Type
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="soilType"
|
||||
value={soilType}
|
||||
onChange={(e) => setSoilType(e.target.value)}
|
||||
className="shadow-xs bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-5">
|
||||
<label
|
||||
htmlFor="soilType"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Size of Land
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="soilType"
|
||||
value={sizeContent}
|
||||
onChange={(e) => setSizeContent(e.target.value)}
|
||||
className="shadow-xs bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||
>
|
||||
Add Farm
|
||||
</button>
|
||||
{error && <p className="mt-4 text-red-500 text-sm">{error}</p>}
|
||||
{success && (
|
||||
<p className="mt-4 text-green-500 text-sm">
|
||||
Farm Updated successfully!
|
||||
</p>
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default UpdateFarm;
|
||||
@@ -1,9 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
const FeedBackAndRatings = () => {
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
export default FeedBackAndRatings
|
||||
@@ -1,10 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
const History = () => {
|
||||
return (
|
||||
<>
|
||||
<div className=""></div></>
|
||||
)
|
||||
}
|
||||
|
||||
export default History
|
||||
@@ -1,261 +0,0 @@
|
||||
import React from "react";
|
||||
import { Link, Outlet, useNavigate } from "react-router-dom";
|
||||
import { BsThreeDotsVertical } from "react-icons/bs";
|
||||
import { RiLogoutBoxLine } from "react-icons/ri";
|
||||
import { IoMdSettings } from "react-icons/io";
|
||||
import { FaHome } from "react-icons/fa";
|
||||
import { useSelector } from "react-redux";
|
||||
import { MdHistory } from "react-icons/md";
|
||||
import { IoIosNotifications } from "react-icons/io";
|
||||
import { MdFeedback } from "react-icons/md";
|
||||
import { MdOutlineSupportAgent } from "react-icons/md";
|
||||
import { IoSettings } from "react-icons/io5";
|
||||
import { RiCalendarScheduleLine } from "react-icons/ri";
|
||||
import { IoIosHome } from "react-icons/io";
|
||||
import { BACKEND_URL } from "../../constants";
|
||||
|
||||
const MainUserPanel = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleLogOut = async () => {
|
||||
const responce = await fetch(`${BACKEND_URL}/api/v1/logout`, {
|
||||
method: "Get",
|
||||
credentials: "include",
|
||||
});
|
||||
|
||||
const data = await responce.json();
|
||||
|
||||
//console.log("User Logged out data is : ", data);
|
||||
|
||||
if (data.success == true) {
|
||||
navigate("/user/login");
|
||||
}
|
||||
};
|
||||
|
||||
const user = useSelector((store) => store.user);
|
||||
return (
|
||||
<>
|
||||
<div className="container mx-auto p-4 ">
|
||||
<div className="flex items-center mb-4 md:hidden">
|
||||
<img
|
||||
src={`${user.avatar}`}
|
||||
alt="Profile Picture"
|
||||
className="rounded-full w-10 h-10 mr-2"
|
||||
/>
|
||||
<span className="text-lg font-medium">Hello, {user.name}</span>
|
||||
</div>
|
||||
<div className="flex flex-row gap-4">
|
||||
<div className="w-1.5/12 md:w-3/12 bg-white rounded-lg shadow p-4">
|
||||
<div className="hidden md:flex items-center mb-4">
|
||||
<img
|
||||
src={`${user.avatar}`}
|
||||
alt="Profile Picture"
|
||||
className="rounded-full w-10 h-10 mr-2"
|
||||
/>
|
||||
<span className="text-lg font-medium">Hello, {user.name}</span>
|
||||
</div>
|
||||
<ul className="list-none">
|
||||
<li className="py-2 border-b border-gray-200">
|
||||
<Link to={"/user/dashboard"} className="flex items-center">
|
||||
<IoIosHome className="text-xl font-bold text-gray-700" />
|
||||
<span className="ml-2 text-sm font-semibold text-gray-500 hidden md:block">
|
||||
Dashboard
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="py-2 border-b border-gray-200">
|
||||
<Link
|
||||
to={"/user/dashboard/scheduledmeetings"}
|
||||
className="flex items-center"
|
||||
>
|
||||
<RiCalendarScheduleLine className="text-xl text-gray-700" />
|
||||
<span className="ml-2 text-sm font-semibold text-gray-500 hidden md:block">
|
||||
Scheduled Meeting
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="py-2 border-b border-gray-200">
|
||||
<Link
|
||||
to={"/user/dashboard/history"}
|
||||
className="flex items-center"
|
||||
>
|
||||
<MdHistory className="text-xl text-gray-700" />
|
||||
<span className="ml-2 text-sm font-semibold text-gray-500 hidden md:block">
|
||||
History
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="py-2 border-b border-gray-200">
|
||||
<Link
|
||||
to={"/user/dashboard/notifications"}
|
||||
className="flex items-center"
|
||||
>
|
||||
<IoIosNotifications className="text-xl text-gray-700" />
|
||||
<span className="ml-2 text-sm font-semibold text-gray-500 hidden md:block">
|
||||
Notifications
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="py-2 border-b border-gray-200">
|
||||
<Link
|
||||
to={"/user/dashboard/feedback"}
|
||||
className="flex items-center"
|
||||
>
|
||||
<MdFeedback className="text-xl text-gray-700" />
|
||||
<span className="ml-2 text-sm font-semibold text-gray-500 hidden md:block">
|
||||
Feedback and Ratings
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="py-2 border-b border-gray-200">
|
||||
<Link
|
||||
to={"/user/dashboard/support"}
|
||||
className="flex items-center"
|
||||
>
|
||||
<MdOutlineSupportAgent className="text-xl text-gray-700" />
|
||||
<span className="ml-2 text-sm font-semibold text-gray-500 hidden md:block">
|
||||
Support
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="py-2 border-b border-gray-200">
|
||||
<Link
|
||||
to={"/user/dashboard/settings"}
|
||||
className="flex items-center"
|
||||
>
|
||||
<IoSettings className="text-xl text-gray-700" />
|
||||
<span className="ml-2 text-sm font-semibold text-gray-500 hidden md:block">
|
||||
Settings
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<Outlet />
|
||||
<div className="hidden md:block w-3/12 bg-white rounded-lg shadow p-4 h-96">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h3 className="text-lg font-medium">My Profile</h3>
|
||||
<div className="flex items-center md:order-2 space-x-3 md:space-x-0 rtl:space-x-reverse">
|
||||
<button
|
||||
type="button"
|
||||
className="flex text-sm rounded-full md:me-0 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600"
|
||||
id="user-menu-button"
|
||||
aria-expanded="false"
|
||||
data-dropdown-toggle="user-dropdown"
|
||||
data-dropdown-placement="bottom"
|
||||
>
|
||||
<span className="sr-only">Open user menu</span>
|
||||
<BsThreeDotsVertical className="text-lg" />
|
||||
</button>
|
||||
{/* <!-- Dropdown menu --> */}
|
||||
<div
|
||||
className="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow dark:bg-gray-700 dark:divide-gray-600"
|
||||
id="user-dropdown"
|
||||
>
|
||||
<div className="px-4 py-3">
|
||||
<span className="block text-sm text-gray-900 dark:text-white">
|
||||
Bonnie Green
|
||||
</span>
|
||||
<span className="block text-sm text-gray-500 truncate dark:text-gray-400">
|
||||
name@flowbite.com
|
||||
</span>
|
||||
</div>
|
||||
<ul className="py-2" aria-labelledby="user-menu-button">
|
||||
<li>
|
||||
<Link
|
||||
to={"/user/dashboard"}
|
||||
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||
>
|
||||
Dashboard
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||
>
|
||||
Settings
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||
>
|
||||
Earnings
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
onClick={handleLogOut}
|
||||
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||
>
|
||||
Sign out
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<button
|
||||
data-collapse-toggle="navbar-user"
|
||||
type="button"
|
||||
class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"
|
||||
aria-controls="navbar-user"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<span className="sr-only">Open main menu</span>
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 17 14"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M1 1h15M1 7h15M1 13h15"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<img
|
||||
src={`${user.avatar}`}
|
||||
alt="Profile Picture"
|
||||
class="rounded-full w-24 h-24 mx-auto"
|
||||
/>
|
||||
<h4 class="text-lg font-medium mt-2">{user.name}</h4>
|
||||
{/* <span class="text-gray-500 text-sm">@thomasdox</span> */}
|
||||
<p class="text-gray-500 text-sm mt-2">
|
||||
Join on {user.createdAt && user.createdAt.substring(0, 10)}
|
||||
</p>
|
||||
<p class="text-gray-500 text-sm mt-2">
|
||||
{user.description == null &&
|
||||
"I am a Senior Software Engineer at Google and also mentored 50+ students to get there dream job."}
|
||||
</p>
|
||||
<div class="flex justify-center mt-4">
|
||||
<button class="bg-gray-300 hover:bg-gray-400 text-gray-700 font-bold py-2 px-4 rounded mr-2">
|
||||
<FaHome className="text-lg font-extrabold" />
|
||||
</button>
|
||||
<button class="bg-gray-300 hover:bg-gray-400 text-gray-700 font-bold py-2 px-4 rounded mr-2">
|
||||
<IoMdSettings className="text-lg font-extrabold" />
|
||||
</button>
|
||||
<button
|
||||
class="bg-gray-300 hover:bg-gray-400 text-gray-700 font-bold py-2 px-4 rounded"
|
||||
onClick={handleLogOut}
|
||||
>
|
||||
<RiLogoutBoxLine className="text-lg font-extrabold" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default MainUserPanel;
|
||||
@@ -1,100 +0,0 @@
|
||||
import React from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
const MentorSessionCard = ({ session }) => {
|
||||
const {
|
||||
id,
|
||||
mentorName,
|
||||
mentorMail,
|
||||
mentorAvatar,
|
||||
studentName,
|
||||
studentMail,
|
||||
studentAvatar,
|
||||
roomid,
|
||||
schduledTime,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
amountPaid,
|
||||
status,
|
||||
} = session;
|
||||
|
||||
const user = useSelector((store) => store.user);
|
||||
|
||||
//console.log("User in the Dashborde : ");
|
||||
|
||||
let timeStringToDayName = (dateStr) => {
|
||||
// for getting day name by time string
|
||||
// const dateStr = "2024-09-26T04:31:50.646+00:00";
|
||||
const date = new Date(dateStr);
|
||||
const dayName = date.toLocaleDateString("en-US", { weekday: "long" });
|
||||
//console.log(dayName);
|
||||
return dayName;
|
||||
};
|
||||
|
||||
let timeStringtoRealTime = (utcDateStr) => {
|
||||
// for converting the to get time in am or pm
|
||||
//const utcDateStr = "2024-09-26T04:31:50.646+00:00";
|
||||
const date = new Date(utcDateStr);
|
||||
// India TimeZone is Asia/Kolkata, which is UTC+5:30
|
||||
const options = {
|
||||
timeZone: "Asia/Kolkata",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
second: "numeric",
|
||||
hour12: true,
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
};
|
||||
|
||||
const istDate = date.toLocaleString("en-US", options);
|
||||
console.log(istDate); // Output: "September 26, 2024, 10:01:50 AM"
|
||||
return istDate;
|
||||
};
|
||||
|
||||
const realTimeString = timeStringtoRealTime(schduledTime);
|
||||
|
||||
return (
|
||||
<>
|
||||
<li class="flex flex-col gap-5 w-full h-auto max-h-28 px-3 py-1 rounded-md hover:bg-slate-100 border-b-2">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0">
|
||||
<img
|
||||
class="w-8 h-8 rounded-full"
|
||||
src="/images/profile.jpeg"
|
||||
alt="Neil image"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex-1 min-w-0 ms-4">
|
||||
<p class="text-sm font-medium text-gray-900 truncate dark:text-white">
|
||||
{user.role === "user" ? mentorName : studentName}
|
||||
</p>
|
||||
<p class="text-sm text-gray-500 truncate dark:text-gray-400">
|
||||
{user.role === "user" ? mentorMail : studentMail}
|
||||
</p>
|
||||
</div>
|
||||
<div class="inline-flex items-center text-base font-semibold text-gray-900 dark:text-white">
|
||||
₹{amountPaid}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<div className="flex items-center">
|
||||
<div>
|
||||
<p className="text-gray-500">
|
||||
{timeStringToDayName(schduledTime)},
|
||||
{realTimeString.substring(21, 26) +
|
||||
" " +
|
||||
realTimeString.substring(30)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<p className="text-gray-500">{realTimeString.substring(0, 18)}</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default MentorSessionCard;
|
||||
@@ -1,47 +0,0 @@
|
||||
// MonitoringPage.jsx
|
||||
import React from "react";
|
||||
import MetricsCard from "../../components/monitoring charts/MetricCard";
|
||||
import PerformanceChart from "../../components/monitoring charts/PerformanceChart";
|
||||
import AlertsPanel from "../../components/monitoring charts/AlertsPanel";
|
||||
import ActivityFeed from "../../components/monitoring charts/ActivityField";
|
||||
import Piechart from "../../components/monitoring charts/Piechart";
|
||||
|
||||
const MonitoringPage = () => {
|
||||
return (
|
||||
<div className="w-full bg-white rounded-lg shadow p-4">
|
||||
<div className="p-6">
|
||||
{/* Summary Metrics */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
|
||||
<MetricsCard title="Active Farms" value="12" />
|
||||
<MetricsCard title="Total Yield" value="3500 kg" />
|
||||
<MetricsCard title="Alerts" value="3" />
|
||||
<MetricsCard title="Uptime" value="99.9%" />
|
||||
</div>
|
||||
|
||||
{/* Performance Trend Chart */}
|
||||
<div className="mb-6 bg-white p-4 rounded-lg shadow">
|
||||
<h2 className="text-lg font-semibold mb-2">Performance Trend</h2>
|
||||
<PerformanceChart />
|
||||
</div>
|
||||
<div className="mb-6 bg-white p-4 rounded-lg shadow">
|
||||
<h2 className="text-lg font-semibold mb-2">Performance Trend</h2>
|
||||
<Piechart></Piechart>
|
||||
</div>
|
||||
|
||||
{/* Alerts and Activity Feed */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="bg-white p-4 rounded-lg shadow">
|
||||
<h2 className="text-lg font-semibold mb-2">Alerts</h2>
|
||||
<AlertsPanel />
|
||||
</div>
|
||||
<div className="bg-white p-4 rounded-lg shadow">
|
||||
<h2 className="text-lg font-semibold mb-2">Recent Activity</h2>
|
||||
<ActivityFeed />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MonitoringPage;
|
||||
@@ -1,120 +0,0 @@
|
||||
import React from "react";
|
||||
import Notification from "../../components/Notification";
|
||||
|
||||
const Notifications = () => {
|
||||
let notifications = [
|
||||
{
|
||||
id: 1,
|
||||
type: "success",
|
||||
message: "Your profile has been updated successfully.",
|
||||
timestamp: "2024-09-26T10:00:00Z",
|
||||
isRead: false,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
type: "warning",
|
||||
message: "Your subscription is about to expire in 3 days.",
|
||||
timestamp: "2024-09-25T09:30:00Z",
|
||||
isRead: false,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
type: "info",
|
||||
message: "New mentor has joined your network.",
|
||||
timestamp: "2024-09-24T15:45:00Z",
|
||||
isRead: false,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
type: "error",
|
||||
message: "Failed to connect to the video call. Please try again.",
|
||||
timestamp: "2024-09-26T08:20:00Z",
|
||||
isRead: false,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
type: "error",
|
||||
message: "Failed to connect to the video call. Please try again.",
|
||||
timestamp: "2024-09-26T08:20:00Z",
|
||||
isRead: false,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
type: "error",
|
||||
message: "Failed to connect to the video call. Please try again.",
|
||||
timestamp: "2024-09-26T08:20:00Z",
|
||||
isRead: false,
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
type: "error",
|
||||
message: "Failed to connect to the video call. Please try again.",
|
||||
timestamp: "2024-09-26T08:20:00Z",
|
||||
isRead: false,
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
type: "error",
|
||||
message: "Failed to connect to the video call. Please try again.",
|
||||
timestamp: "2024-09-26T08:20:00Z",
|
||||
isRead: false,
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
type: "error",
|
||||
message: "Failed to connect to the video call. Please try again.",
|
||||
timestamp: "2024-09-26T08:20:00Z",
|
||||
isRead: false,
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
type: "error",
|
||||
message: "Failed to connect to the video call. Please try again.",
|
||||
timestamp: "2024-09-26T08:20:00Z",
|
||||
isRead: false,
|
||||
},
|
||||
];
|
||||
|
||||
// for getting day name by time string
|
||||
// const dateStr = '2024-09-26T04:31:50.646+00:00';
|
||||
// const date = new Date(dateStr);
|
||||
// const dayName = date.toLocaleDateString('en-US', { weekday: 'long' });
|
||||
// console.log(dayName); // Output: "Thursday"
|
||||
|
||||
// for converting the to get time in am or pm
|
||||
// const utcDateStr = '2024-09-26T04:31:50.646+00:00';
|
||||
// const date = new Date(utcDateStr);
|
||||
// India TimeZone is Asia/Kolkata, which is UTC+5:30
|
||||
// const options = {
|
||||
// timeZone: 'Asia/Kolkata',
|
||||
// hour: 'numeric',
|
||||
// minute: 'numeric',
|
||||
// second: 'numeric',
|
||||
// hour12: true,
|
||||
// year: 'numeric',
|
||||
// month: 'long',
|
||||
// day: 'numeric'
|
||||
// };
|
||||
|
||||
// const istDate = date.toLocaleString('en-US', options);
|
||||
// console.log(istDate); // Output: "September 26, 2024, 10:01:50 AM"
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full bg-white rounded-lg shadow p-4 min-h-[85vh]">
|
||||
<div className="flex flex-col justify-center items-center mb-4">
|
||||
<h2 className="text-2xl font-bold font-sans border-b-2 py-2">
|
||||
Notifications
|
||||
</h2>
|
||||
</div>
|
||||
<div className="flex flex-col w-full gap-2">
|
||||
{notifications.map((notification) => (
|
||||
<Notification key={notification.id} notification={notification} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Notifications;
|
||||
@@ -1,131 +0,0 @@
|
||||
import React from "react";
|
||||
import MentorSessionCard from "./MentorSessionCard";
|
||||
|
||||
const ScheduleMeeting = () => {
|
||||
let meetingInfo = [
|
||||
{
|
||||
id: "7K6dU5qLpF9tS4",
|
||||
mentorName: "mentor",
|
||||
mentorMail: "mentor4@gmail.com",
|
||||
mentorAvatar: "/images/profile4.jpeg",
|
||||
studentName: "student",
|
||||
studentMail: "student4@gmail.com",
|
||||
studentAvatar: "/images/profile4.jpeg",
|
||||
roomid: "F7mT9rV5uP3sL2K7cJ8xH4zG1yW5aQ9nD2o",
|
||||
schduledTime: "2024-09-29T11:20:40.456+00:00",
|
||||
createdAt: "2024-09-29T11:20:40.456+00:00",
|
||||
updatedAt: "2024-09-29T11:20:40.456+00:00",
|
||||
amountPaid: "550",
|
||||
status: false,
|
||||
},
|
||||
{
|
||||
id: "7K6dU5qLpF9tS4",
|
||||
mentorName: "mentor",
|
||||
mentorMail: "mentor4@gmail.com",
|
||||
mentorAvatar: "/images/profile4.jpeg",
|
||||
studentName: "student",
|
||||
studentMail: "student4@gmail.com",
|
||||
studentAvatar: "/images/profile4.jpeg",
|
||||
roomid: "F7mT9rV5uP3sL2K7cJ8xH4zG1yW5aQ9nD2o",
|
||||
schduledTime: "2024-09-29T11:20:40.456+00:00",
|
||||
createdAt: "2024-09-29T11:20:40.456+00:00",
|
||||
updatedAt: "2024-09-29T11:20:40.456+00:00",
|
||||
amountPaid: "550",
|
||||
status: false,
|
||||
},
|
||||
{
|
||||
id: "7K6dU5qLpF9tS4",
|
||||
mentorName: "mentor",
|
||||
mentorMail: "mentor4@gmail.com",
|
||||
mentorAvatar: "/images/profile4.jpeg",
|
||||
studentName: "student",
|
||||
studentMail: "student4@gmail.com",
|
||||
studentAvatar: "/images/profile4.jpeg",
|
||||
roomid: "F7mT9rV5uP3sL2K7cJ8xH4zG1yW5aQ9nD2o",
|
||||
schduledTime: "2024-09-29T11:20:40.456+00:00",
|
||||
createdAt: "2024-09-29T11:20:40.456+00:00",
|
||||
updatedAt: "2024-09-29T11:20:40.456+00:00",
|
||||
amountPaid: "550",
|
||||
status: false,
|
||||
},
|
||||
{
|
||||
id: "7K6dU5qLpF9tS4",
|
||||
mentorName: "mentor",
|
||||
mentorMail: "mentor4@gmail.com",
|
||||
mentorAvatar: "/images/profile4.jpeg",
|
||||
studentName: "student",
|
||||
studentMail: "student4@gmail.com",
|
||||
studentAvatar: "/images/profile4.jpeg",
|
||||
roomid: "F7mT9rV5uP3sL2K7cJ8xH4zG1yW5aQ9nD2o",
|
||||
schduledTime: "2024-09-29T11:20:40.456+00:00",
|
||||
createdAt: "2024-09-29T11:20:40.456+00:00",
|
||||
updatedAt: "2024-09-29T11:20:40.456+00:00",
|
||||
amountPaid: "550",
|
||||
status: false,
|
||||
},
|
||||
{
|
||||
id: "7K6dU5qLpF9tS4",
|
||||
mentorName: "mentor",
|
||||
mentorMail: "mentor4@gmail.com",
|
||||
mentorAvatar: "/images/profile4.jpeg",
|
||||
studentName: "student",
|
||||
studentMail: "student4@gmail.com",
|
||||
studentAvatar: "/images/profile4.jpeg",
|
||||
roomid: "F7mT9rV5uP3sL2K7cJ8xH4zG1yW5aQ9nD2o",
|
||||
schduledTime: "2024-09-29T11:20:40.456+00:00",
|
||||
createdAt: "2024-09-29T11:20:40.456+00:00",
|
||||
updatedAt: "2024-09-29T11:20:40.456+00:00",
|
||||
amountPaid: "550",
|
||||
status: false,
|
||||
},
|
||||
{
|
||||
id: "7K6dU5qLpF9tS4",
|
||||
mentorName: "mentor",
|
||||
mentorMail: "mentor4@gmail.com",
|
||||
mentorAvatar: "/images/profile4.jpeg",
|
||||
studentName: "student",
|
||||
studentMail: "student4@gmail.com",
|
||||
studentAvatar: "/images/profile4.jpeg",
|
||||
roomid: "F7mT9rV5uP3sL2K7cJ8xH4zG1yW5aQ9nD2o",
|
||||
schduledTime: "2024-09-29T11:20:40.456+00:00",
|
||||
createdAt: "2024-09-29T11:20:40.456+00:00",
|
||||
updatedAt: "2024-09-29T11:20:40.456+00:00",
|
||||
amountPaid: "550",
|
||||
status: false,
|
||||
},
|
||||
{
|
||||
id: "7K6dU5qLpF9tS4",
|
||||
mentorName: "mentor",
|
||||
mentorMail: "mentor4@gmail.com",
|
||||
mentorAvatar: "/images/profile4.jpeg",
|
||||
studentName: "student",
|
||||
studentMail: "student4@gmail.com",
|
||||
studentAvatar: "/images/profile4.jpeg",
|
||||
roomid: "F7mT9rV5uP3sL2K7cJ8xH4zG1yW5aQ9nD2o",
|
||||
schduledTime: "2024-09-29T11:20:40.456+00:00",
|
||||
createdAt: "2024-09-29T11:20:40.456+00:00",
|
||||
updatedAt: "2024-09-29T11:20:40.456+00:00",
|
||||
amountPaid: "550",
|
||||
status: false,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full bg-white rounded-lg shadow p-4 min-h-[85vh]">
|
||||
<div className="flex flex-col justify-center items-center mb-4">
|
||||
<h2 className="text-2xl font-bold font-sans border-b-2 py-2">
|
||||
Scheduled Meetings
|
||||
</h2>
|
||||
</div>
|
||||
<div className="flex w-full flex-col gap-5">
|
||||
{meetingInfo.map((session) => (
|
||||
<MentorSessionCard session={session} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ScheduleMeeting;
|
||||
@@ -1,273 +0,0 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { loaderSliceActions } from "../../store/loaderSlice";
|
||||
import { userSliceActions } from "../../store/userSlice";
|
||||
import { BACKEND_URL } from "../../constants";
|
||||
|
||||
const Settings = () => {
|
||||
const nameElement = useRef();
|
||||
const emailElement = useRef();
|
||||
const passwordElement = useRef();
|
||||
const confirmPassElement = useRef();
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
const [avatar, setAvatar] = useState();
|
||||
|
||||
const user = useSelector((store) => store.user);
|
||||
|
||||
const loader = useSelector((store) => store.loader);
|
||||
|
||||
//console.log("Before the user is : ", user);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
// Optimise the call for the database here you are refreshing the page again and again which makes read and write operation
|
||||
const handleAvatar = async (event) => {
|
||||
event.preventDefault();
|
||||
formData.append("avatar", avatar);
|
||||
|
||||
//console.log("forma daata is : ", formData);
|
||||
|
||||
if (avatar) {
|
||||
dispatch(loaderSliceActions.showLoader());
|
||||
//console.log("The loader values is : ", loader);
|
||||
const responce = await fetch(`${BACKEND_URL}/api/v1/user/avatar`, {
|
||||
method: "PUT",
|
||||
credentials: "include",
|
||||
body: formData,
|
||||
});
|
||||
|
||||
const finalResponce = await responce.json();
|
||||
|
||||
//console.log("Our final responce is : ", finalResponce);
|
||||
|
||||
if (finalResponce.success) {
|
||||
dispatch(loaderSliceActions.hideLoader());
|
||||
//console.log("The loader values is : ", loader);
|
||||
dispatch(userSliceActions.addUser(finalResponce.data));
|
||||
// console.log("Updated User is : ", user);
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleLogin = async (event) => {
|
||||
event.preventDefault();
|
||||
const responce = await fetch(`${BACKEND_URL}/api/v1/login`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: emailElement.current.value,
|
||||
password: passwordElement.current.value,
|
||||
}),
|
||||
});
|
||||
|
||||
const user = await responce.json();
|
||||
|
||||
//console.log("User Login Data is here : ", user);
|
||||
|
||||
dispatch(userSliceActions.addUser(user.data));
|
||||
|
||||
emailElement.current.value = "";
|
||||
passwordElement.current.value = "";
|
||||
|
||||
if (user.success == true) {
|
||||
navigate("/");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<>
|
||||
<div className="w-full bg-white rounded-lg shadow p-4 min-h-[85vh]">
|
||||
<div className="flex flex-col justify-center items-center mb-4">
|
||||
<h2 className="text-2xl font-bold font-sans border-b-2 py-2">
|
||||
Update Your Avatar
|
||||
</h2>
|
||||
|
||||
<div className="w-full h-auto flex items-center justify-center py-7">
|
||||
<div className="w-[9rem] h-[9rem] overflow-hidden rounded-full object-center">
|
||||
<img src={`${user.avatar}`} alt="Avatar" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form onSubmit={handleAvatar}>
|
||||
<div class="flex items-center justify-center w-full">
|
||||
<img src={formData.avatar && `${formData.avatar}`} alt="" />
|
||||
<label
|
||||
for="dropzone-file"
|
||||
class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600"
|
||||
>
|
||||
<div class="flex flex-col items-center justify-center pt-5 pb-6 ">
|
||||
<svg
|
||||
class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 20 16"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2"
|
||||
/>
|
||||
</svg>
|
||||
<p class="mb-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
{avatar ? (
|
||||
<span class="font-semibold">
|
||||
Avatar uploaded successfulky
|
||||
</span>
|
||||
) : (
|
||||
<span class="font-semibold">
|
||||
Click to upload and press Upload button
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
SVG, PNG, JPG or GIF (MAX. 800x400px)
|
||||
</p>
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-gray-600 px-4 py-1 rounded-lg text-white font-semibold my-4"
|
||||
>
|
||||
Upload
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
id="dropzone-file"
|
||||
type="file"
|
||||
class="hidden"
|
||||
onChange={(e) => {
|
||||
setAvatar(e.target.files[0]);
|
||||
//console.log(e.target.files[0]);
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="flex flex-col justify-center items-center mb-4">
|
||||
<h2 className="text-2xl font-bold font-sans border-b-2 py-2">
|
||||
Update Your Details
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<form className="space-y-6" onSubmit={handleLogin}>
|
||||
<div>
|
||||
<label
|
||||
for="password"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Name :
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="password"
|
||||
ref={nameElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Enter your Updated Name here.."
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
for="username"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Email :
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="username"
|
||||
ref={emailElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Enter your Updated Email here.."
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
{/* <div>
|
||||
<label
|
||||
for="password"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
ref={passwordElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="********"
|
||||
required
|
||||
/>
|
||||
</div> */}
|
||||
<div className="flex justify-center items-center">
|
||||
<button
|
||||
type="submit"
|
||||
className="text-white bg-purple-500 hover:bg-purple-700 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||
>
|
||||
Change the Details
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="flex flex-col justify-center items-center my-10">
|
||||
<h2 className="text-2xl font-bold font-sans border-b-2 py-2">
|
||||
Update Your Password
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<form className="space-y-6" onSubmit={handleLogin}>
|
||||
<div>
|
||||
<label
|
||||
for="password"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
New Password :
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
ref={passwordElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Enter your New Password to update.."
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
for="password"
|
||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Confirm Password :
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
ref={confirmPassElement}
|
||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Enter your New Password to update.."
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-center items-center">
|
||||
<button
|
||||
type="submit"
|
||||
className="text-white bg-purple-500 hover:bg-purple-700 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||
>
|
||||
Change the Password
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Settings;
|
||||
@@ -1,11 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const Support = () => {
|
||||
return (
|
||||
<>
|
||||
<div className=""></div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Support;
|
||||
@@ -1,41 +0,0 @@
|
||||
class PeerService {
|
||||
constructor() {
|
||||
if (!this.peer) {
|
||||
this.peer = new RTCPeerConnection({
|
||||
iceServers: [
|
||||
{
|
||||
urls: [
|
||||
"stun:stun.l.google.com:19302",
|
||||
"stun:global.stun.twilio.com:3478",
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async getAnswer(offer) {
|
||||
if (this.peer) {
|
||||
await this.peer.setRemoteDescription(offer);
|
||||
const ans = await this.peer.createAnswer();
|
||||
await this.peer.setLocalDescription(new RTCSessionDescription(ans));
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
|
||||
async setLocalDescription(ans) {
|
||||
if (this.peer) {
|
||||
await this.peer.setRemoteDescription(new RTCSessionDescription(ans));
|
||||
}
|
||||
}
|
||||
|
||||
async getOffer() {
|
||||
if (this.peer) {
|
||||
const offer = await this.peer.createOffer();
|
||||
await this.peer.setLocalDescription(new RTCSessionDescription(offer));
|
||||
return offer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new PeerService();
|
||||
@@ -1,14 +0,0 @@
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import userSlice from "./userSlice";
|
||||
import messageSlice from "./messageSlice";
|
||||
import loaderSlice from "./loaderSlice";
|
||||
|
||||
const MentifyStore = configureStore({
|
||||
reducer: {
|
||||
user: userSlice.reducer,
|
||||
messages: messageSlice.reducer,
|
||||
loader: loaderSlice.reducer,
|
||||
},
|
||||
});
|
||||
|
||||
export default MentifyStore;
|
||||
@@ -1,18 +0,0 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const loaderSlice = createSlice({
|
||||
name: "loader",
|
||||
initialState: false,
|
||||
reducers: {
|
||||
showLoader: (state) => {
|
||||
return true;
|
||||
},
|
||||
hideLoader: (state) => {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const loaderSliceActions = loaderSlice.actions;
|
||||
|
||||
export default loaderSlice;
|
||||
@@ -1,15 +0,0 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const messageSlice = createSlice({
|
||||
name: "messages",
|
||||
initialState: [],
|
||||
reducers: {
|
||||
addMessage: (state, action) => {
|
||||
return [...state, action.payload];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const messageActions = messageSlice.actions;
|
||||
|
||||
export default messageSlice;
|
||||
@@ -1,20 +0,0 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
const userSlice = createSlice({
|
||||
name: "user",
|
||||
initialState: {
|
||||
name: "Unloggedin User",
|
||||
email: "Unlogged@gmail.com",
|
||||
avatar: "/images/default1.png",
|
||||
role: "unloggeduser",
|
||||
mainInterest: [],
|
||||
},
|
||||
reducers: {
|
||||
addUser: (state, action) => {
|
||||
return (state = action.payload);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const userSliceActions = userSlice.actions;
|
||||
|
||||
export default userSlice;
|
||||
@@ -1,14 +0,0 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
<<<<<<< HEAD
|
||||
darkMode: 'class', // Change this based on your needs
|
||||
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
'plant': "url('/home/atharva/public/images/plant-1573.svg')",
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"rewrites": [
|
||||
{
|
||||
"source": "/(.*)",
|
||||
"destination": "/"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
@@ -1,119 +0,0 @@
|
||||
{
|
||||
"name": "git repo",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/@yr/monotone-cubic-spline": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
|
||||
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/apexcharts": {
|
||||
"version": "3.46.0",
|
||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.46.0.tgz",
|
||||
"integrity": "sha512-ELAY6vj8JQD7QLktKasTzwm9Wt0qxqfQSo+3QWS7G7I774iK8HCkG1toGsqJH0mkK6PtYBtnSIe66uUcwoCw1w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@yr/monotone-cubic-spline": "^1.0.3",
|
||||
"svg.draggable.js": "^2.2.2",
|
||||
"svg.easing.js": "^2.0.0",
|
||||
"svg.filter.js": "^2.0.2",
|
||||
"svg.pathmorphing.js": "^0.1.3",
|
||||
"svg.resize.js": "^1.4.3",
|
||||
"svg.select.js": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.draggable.js": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz",
|
||||
"integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.easing.js": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz",
|
||||
"integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"svg.js": ">=2.3.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.filter.js": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz",
|
||||
"integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.js": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz",
|
||||
"integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/svg.pathmorphing.js": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz",
|
||||
"integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.resize.js": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz",
|
||||
"integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.6.5",
|
||||
"svg.select.js": "^2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.resize.js/node_modules/svg.select.js": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz",
|
||||
"integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.select.js": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz",
|
||||
"integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.6.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
.DS_Store
|
||||
.git*
|
||||
test
|
||||
package-lock.json
|
||||
@@ -1,5 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "4"
|
||||
- "6"
|
||||
sudo: false
|
||||
@@ -1,20 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 yr.no
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,23 +0,0 @@
|
||||
[](https://npmjs.org/package/@yr/monotone-cubic-spline)
|
||||
[](https://travis-ci.org/YR/monotone-cubic-spline?branch=master)
|
||||
|
||||
Convert a series of points to a monotone cubic spline (based on D3.js implementation)
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const spline = require('@yr/monotone-cubic-spline');
|
||||
const points = spline.points([[0,0], [1,1], [2,1], [3,0], [4,0]]);
|
||||
const svgPath = spline.svgPath(points);
|
||||
|
||||
console.log(svgPath);
|
||||
// => 'M0 0C0.08333333333333333, 0.08333333333333333, ...'
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
**points(points)**: convert array of points (x,y) to array of bezier points (c1x,c1y,c2x,c2y,x,y)
|
||||
|
||||
**slice(points, start, end)**: slice a segment of converted points
|
||||
|
||||
**svgPath(points)**: convert array of bezier points to svg path (`d`) string
|
||||
@@ -1,166 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Convert a series of points to a monotone cubic spline
|
||||
* Algorithm based on https://github.com/mbostock/d3
|
||||
* https://github.com/yr/monotone-cubic-spline
|
||||
* @copyright Yr
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
var ε = 1e-6;
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Convert 'points' to bezier
|
||||
* @param {Array} points
|
||||
* @returns {Array}
|
||||
*/
|
||||
points: function points(_points) {
|
||||
var tgts = tangents(_points);
|
||||
|
||||
var p = _points[1];
|
||||
var p0 = _points[0];
|
||||
var pts = [];
|
||||
var t = tgts[1];
|
||||
var t0 = tgts[0];
|
||||
|
||||
// Add starting 'M' and 'C' points
|
||||
pts.push(p0, [p0[0] + t0[0], p0[1] + t0[1], p[0] - t[0], p[1] - t[1], p[0], p[1]]);
|
||||
|
||||
// Add 'S' points
|
||||
for (var i = 2, n = tgts.length; i < n; i++) {
|
||||
var _p = _points[i];
|
||||
var _t = tgts[i];
|
||||
|
||||
pts.push([_p[0] - _t[0], _p[1] - _t[1], _p[0], _p[1]]);
|
||||
}
|
||||
|
||||
return pts;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Slice out a segment of 'points'
|
||||
* @param {Array} points
|
||||
* @param {Number} start
|
||||
* @param {Number} end
|
||||
* @returns {Array}
|
||||
*/
|
||||
slice: function slice(points, start, end) {
|
||||
var pts = points.slice(start, end);
|
||||
|
||||
if (start) {
|
||||
// Add additional 'C' points
|
||||
if (pts[1].length < 6) {
|
||||
var n = pts[0].length;
|
||||
|
||||
pts[1] = [pts[0][n - 2] * 2 - pts[0][n - 4], pts[0][n - 1] * 2 - pts[0][n - 3]].concat(pts[1]);
|
||||
}
|
||||
// Remove control points for 'M'
|
||||
pts[0] = pts[0].slice(-2);
|
||||
}
|
||||
|
||||
return pts;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Convert 'points' to svg path
|
||||
* @param {Array} points
|
||||
* @returns {String}
|
||||
*/
|
||||
svgPath: function svgPath(points) {
|
||||
var p = '';
|
||||
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
var point = points[i];
|
||||
var n = point.length;
|
||||
|
||||
if (!i) {
|
||||
p += 'M' + point[n - 2] + ' ' + point[n - 1];
|
||||
} else if (n > 4) {
|
||||
p += 'C' + point[0] + ', ' + point[1];
|
||||
p += ', ' + point[2] + ', ' + point[3];
|
||||
p += ', ' + point[4] + ', ' + point[5];
|
||||
} else {
|
||||
p += 'S' + point[0] + ', ' + point[1];
|
||||
p += ', ' + point[2] + ', ' + point[3];
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate tangents for 'points'
|
||||
* @param {Array} points
|
||||
* @returns {Array}
|
||||
*/
|
||||
function tangents(points) {
|
||||
var m = finiteDifferences(points);
|
||||
var n = points.length - 1;
|
||||
|
||||
var tgts = [];
|
||||
var a = void 0,
|
||||
b = void 0,
|
||||
d = void 0,
|
||||
s = void 0;
|
||||
|
||||
for (var i = 0; i < n; i++) {
|
||||
d = slope(points[i], points[i + 1]);
|
||||
|
||||
if (Math.abs(d) < ε) {
|
||||
m[i] = m[i + 1] = 0;
|
||||
} else {
|
||||
a = m[i] / d;
|
||||
b = m[i + 1] / d;
|
||||
s = a * a + b * b;
|
||||
if (s > 9) {
|
||||
s = d * 3 / Math.sqrt(s);
|
||||
m[i] = s * a;
|
||||
m[i + 1] = s * b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var _i = 0; _i <= n; _i++) {
|
||||
s = (points[Math.min(n, _i + 1)][0] - points[Math.max(0, _i - 1)][0]) / (6 * (1 + m[_i] * m[_i]));
|
||||
tgts.push([s || 0, m[_i] * s || 0]);
|
||||
}
|
||||
|
||||
return tgts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute slope from point 'p0' to 'p1'
|
||||
* @param {Array} p0
|
||||
* @param {Array} p1
|
||||
* @returns {Number}
|
||||
*/
|
||||
function slope(p0, p1) {
|
||||
return (p1[1] - p0[1]) / (p1[0] - p0[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute three-point differences for 'points'
|
||||
* @param {Array} points
|
||||
* @returns {Array}
|
||||
*/
|
||||
function finiteDifferences(points) {
|
||||
var m = [];
|
||||
var p0 = points[0];
|
||||
var p1 = points[1];
|
||||
var d = m[0] = slope(p0, p1);
|
||||
var i = 1;
|
||||
|
||||
for (var n = points.length - 1; i < n; i++) {
|
||||
p0 = p1;
|
||||
p1 = points[i + 1];
|
||||
m[i] = (d + (d = slope(p0, p1))) * 0.5;
|
||||
}
|
||||
m[i] = d;
|
||||
|
||||
return m;
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
{
|
||||
"name": "@yr/monotone-cubic-spline",
|
||||
"description": "Convert a series of points to a monotone cubic spline",
|
||||
"version": "1.0.3",
|
||||
"author": "Alexander Pope <alexander.pope@nrk.no>",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"babel-plugin-syntax-trailing-function-commas": "6.22.0",
|
||||
"babel-plugin-transform-async-generator-functions": "6.24.1",
|
||||
"babel-plugin-transform-async-to-generator": "6.24.1",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "6.22.0",
|
||||
"babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
|
||||
"babel-plugin-transform-es2015-block-scoping": "6.24.1",
|
||||
"babel-plugin-transform-es2015-classes": "6.24.1",
|
||||
"babel-plugin-transform-es2015-computed-properties": "6.24.1",
|
||||
"babel-plugin-transform-es2015-destructuring": "6.23.0",
|
||||
"babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
|
||||
"babel-plugin-transform-es2015-for-of": "6.23.0",
|
||||
"babel-plugin-transform-es2015-function-name": "6.24.1",
|
||||
"babel-plugin-transform-es2015-literals": "6.22.0",
|
||||
"babel-plugin-transform-es2015-object-super": "6.24.1",
|
||||
"babel-plugin-transform-es2015-parameters": "6.24.1",
|
||||
"babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
|
||||
"babel-plugin-transform-es2015-spread": "6.22.0",
|
||||
"babel-plugin-transform-es2015-sticky-regex": "6.24.1",
|
||||
"babel-plugin-transform-es2015-template-literals": "6.22.0",
|
||||
"babel-plugin-transform-es2015-unicode-regex": "6.24.1",
|
||||
"babel-plugin-transform-es5-property-mutators": "6.24.1",
|
||||
"babel-plugin-transform-exponentiation-operator": "6.24.1",
|
||||
"babel-plugin-transform-object-rest-spread": "6.23.0",
|
||||
"buddy": "6.x.x",
|
||||
"expect.js": "*",
|
||||
"mocha": "*"
|
||||
},
|
||||
"main": "src/index.js",
|
||||
"repository": "https://github.com/YR/monotone-cubic-spline.git",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"prepublish": "buddy build",
|
||||
"test": "NODE_ENV=test mocha test/lib-test.js --reporter spec"
|
||||
},
|
||||
"browser": "index.js",
|
||||
"buddy": {
|
||||
"build": [
|
||||
{
|
||||
"input": "src/",
|
||||
"output": ".",
|
||||
"bundle": false,
|
||||
"version": "es5"
|
||||
},
|
||||
{
|
||||
"input": "src/index.js",
|
||||
"output": "test/lib.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Convert a series of points to a monotone cubic spline
|
||||
* Algorithm based on https://github.com/mbostock/d3
|
||||
* https://github.com/yr/monotone-cubic-spline
|
||||
* @copyright Yr
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
const ε = 1e-6;
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Convert 'points' to bezier
|
||||
* @param {Array} points
|
||||
* @returns {Array}
|
||||
*/
|
||||
points(points) {
|
||||
const tgts = tangents(points);
|
||||
|
||||
const p = points[1];
|
||||
const p0 = points[0];
|
||||
const pts = [];
|
||||
const t = tgts[1];
|
||||
const t0 = tgts[0];
|
||||
|
||||
// Add starting 'M' and 'C' points
|
||||
pts.push(p0, [p0[0] + t0[0], p0[1] + t0[1], p[0] - t[0], p[1] - t[1], p[0], p[1]]);
|
||||
|
||||
// Add 'S' points
|
||||
for (let i = 2, n = tgts.length; i < n; i++) {
|
||||
const p = points[i];
|
||||
const t = tgts[i];
|
||||
|
||||
pts.push([p[0] - t[0], p[1] - t[1], p[0], p[1]]);
|
||||
}
|
||||
|
||||
return pts;
|
||||
},
|
||||
|
||||
/**
|
||||
* Slice out a segment of 'points'
|
||||
* @param {Array} points
|
||||
* @param {Number} start
|
||||
* @param {Number} end
|
||||
* @returns {Array}
|
||||
*/
|
||||
slice(points, start, end) {
|
||||
const pts = points.slice(start, end);
|
||||
|
||||
if (start) {
|
||||
// Add additional 'C' points
|
||||
if (pts[1].length < 6) {
|
||||
const n = pts[0].length;
|
||||
|
||||
pts[1] = [pts[0][n - 2] * 2 - pts[0][n - 4], pts[0][n - 1] * 2 - pts[0][n - 3]].concat(pts[1]);
|
||||
}
|
||||
// Remove control points for 'M'
|
||||
pts[0] = pts[0].slice(-2);
|
||||
}
|
||||
|
||||
return pts;
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert 'points' to svg path
|
||||
* @param {Array} points
|
||||
* @returns {String}
|
||||
*/
|
||||
svgPath(points) {
|
||||
let p = '';
|
||||
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const point = points[i];
|
||||
const n = point.length;
|
||||
|
||||
if (!i) {
|
||||
p += `M${point[n - 2]} ${point[n - 1]}`;
|
||||
} else if (n > 4) {
|
||||
p += `C${point[0]}, ${point[1]}`;
|
||||
p += `, ${point[2]}, ${point[3]}`;
|
||||
p += `, ${point[4]}, ${point[5]}`;
|
||||
} else {
|
||||
p += `S${point[0]}, ${point[1]}`;
|
||||
p += `, ${point[2]}, ${point[3]}`;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate tangents for 'points'
|
||||
* @param {Array} points
|
||||
* @returns {Array}
|
||||
*/
|
||||
function tangents(points) {
|
||||
const m = finiteDifferences(points);
|
||||
const n = points.length - 1;
|
||||
|
||||
const tgts = [];
|
||||
let a, b, d, s;
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
d = slope(points[i], points[i + 1]);
|
||||
|
||||
if (Math.abs(d) < ε) {
|
||||
m[i] = m[i + 1] = 0;
|
||||
} else {
|
||||
a = m[i] / d;
|
||||
b = m[i + 1] / d;
|
||||
s = a * a + b * b;
|
||||
if (s > 9) {
|
||||
s = d * 3 / Math.sqrt(s);
|
||||
m[i] = s * a;
|
||||
m[i + 1] = s * b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i <= n; i++) {
|
||||
s = (points[Math.min(n, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i]));
|
||||
tgts.push([s || 0, m[i] * s || 0]);
|
||||
}
|
||||
|
||||
return tgts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute slope from point 'p0' to 'p1'
|
||||
* @param {Array} p0
|
||||
* @param {Array} p1
|
||||
* @returns {Number}
|
||||
*/
|
||||
function slope(p0, p1) {
|
||||
return (p1[1] - p0[1]) / (p1[0] - p0[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute three-point differences for 'points'
|
||||
* @param {Array} points
|
||||
* @returns {Array}
|
||||
*/
|
||||
function finiteDifferences(points) {
|
||||
const m = [];
|
||||
let p0 = points[0];
|
||||
let p1 = points[1];
|
||||
let d = (m[0] = slope(p0, p1));
|
||||
let i = 1;
|
||||
|
||||
for (let n = points.length - 1; i < n; i++) {
|
||||
p0 = p1;
|
||||
p1 = points[i + 1];
|
||||
m[i] = (d + (d = slope(p0, p1))) * 0.5;
|
||||
}
|
||||
m[i] = d;
|
||||
|
||||
return m;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 ApexCharts
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,230 +0,0 @@
|
||||
<p align="center"><img src="https://apexcharts.com/media/apexcharts-logo.png"></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/apexcharts/apexcharts.js/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-brightgreen.svg" alt="License"></a>
|
||||
<a href="https://travis-ci.com/apexcharts/apexcharts.js"><img src="https://api.travis-ci.com/apexcharts/apexcharts.js.svg?branch=master" alt="build" /></a>
|
||||
<img alt="downloads" src="https://img.shields.io/npm/dm/apexcharts.svg"/>
|
||||
<a href="https://www.npmjs.com/package/apexcharts"><img src="https://img.shields.io/npm/v/apexcharts.svg" alt="ver"></a>
|
||||
<img alt="size" src="https://badgen.net/bundlephobia/min/apexcharts?label=size">
|
||||
<a href="https://cdn.jsdelivr.net/npm/apexcharts@3.12.0/types/apexcharts.d.ts"><img src="https://badgen.net/npm/types/apexcharts"/></a>
|
||||
<a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square" alt="prettier"></a>
|
||||
<a href="https://www.jsdelivr.com/package/npm/apexcharts"><img src="https://data.jsdelivr.com/v1/package/npm/apexcharts/badge" alt="jsdelivr" /></a>
|
||||
<a href="https://codeclimate.com/github/apexcharts/apexcharts.js"><img src="https://badgen.net/codeclimate/maintainability/apexcharts/apexcharts.js" /></a>
|
||||
<img src="https://badgen.net/codeclimate/tech-debt/apexcharts/apexcharts.js"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://twitter.com/intent/tweet?text=Create%20visualizations%20with%20this%20free%20and%20open-source%20JavaScript%20Chart%20library&url=https://www.apexcharts.com&hashtags=javascript,charts,visualizations,developers,apexcharts"><img src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
|
||||
</p>
|
||||
|
||||
<p align="center">A modern JavaScript charting library that allows you to build interactive data visualizations with simple API and 100+ ready-to-use samples. Packed with the features that you expect, ApexCharts includes over a dozen chart types that deliver beautiful, responsive visualizations in your apps and dashboards. ApexCharts is an MIT-licensed open-source project that can be used in commercial and non-commercial projects.</p>
|
||||
|
||||
<p align="center"><a href="https://apexcharts.com/javascript-chart-demos/"><img
|
||||
src="https://apexcharts.com/media/apexcharts-banner.png"></a></p>
|
||||
|
||||
<br />
|
||||
|
||||
## Browsers support
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/> Edge | [<img src="https://user-images.githubusercontent.com/17712401/124668393-30772d00-de87-11eb-9360-3199c3b68b95.png" alt="IE" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/> IE11 |
|
||||
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| 31+ ✔ | 35+ ✔ | 6+ ✔ | Edge ✔ | [(IE11)](#using-it-with-ie11) ✔ |
|
||||
|
||||
## Download and Installation
|
||||
|
||||
##### Installing via npm
|
||||
|
||||
```bash
|
||||
npm install apexcharts --save
|
||||
```
|
||||
|
||||
##### Direct <script> include
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
||||
```
|
||||
|
||||
## Wrappers for Vue/React/Angular/Stencil
|
||||
|
||||
Integrate easily with 3rd party frameworks
|
||||
|
||||
- [vue-apexcharts](https://github.com/apexcharts/vue-apexcharts)
|
||||
- [react-apexcharts](https://github.com/apexcharts/react-apexcharts)
|
||||
- [ng-apexcharts](https://github.com/apexcharts/ng-apexcharts) - Plugin by [Morris Janatzek](https://morrisj.net/)
|
||||
- [stencil-apexcharts](https://github.com/apexcharts/stencil-apexcharts)
|
||||
|
||||
### Unofficial Wrappers
|
||||
|
||||
Useful links to wrappers other than the popular frameworks mentioned above
|
||||
|
||||
- [apexcharter](https://github.com/dreamRs/apexcharter) - Htmlwidget for ApexCharts
|
||||
- [apexcharts.rb](https://github.com/styd/apexcharts.rb) - Ruby wrapper for ApexCharts
|
||||
- [larapex-charts](https://github.com/ArielMejiaDev/larapex-charts) - Laravel wrapper for ApexCharts
|
||||
- [blazor-apexcharts](https://github.com/apexcharts/Blazor-ApexCharts) - Blazor wrapper for ApexCharts [demo](https://apexcharts.github.io/Blazor-ApexCharts/)
|
||||
- [svelte-apexcharts](https://github.com/galkatz373/svelte-apexcharts) - Svelte wrapper for ApexCharts
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import ApexCharts from 'apexcharts'
|
||||
```
|
||||
|
||||
To create a basic bar chart with minimal configuration, write as follows:
|
||||
|
||||
```js
|
||||
var options = {
|
||||
chart: {
|
||||
type: 'bar'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'sales',
|
||||
data: [30, 40, 35, 50, 49, 60, 70, 91, 125]
|
||||
}
|
||||
],
|
||||
xaxis: {
|
||||
categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999]
|
||||
}
|
||||
}
|
||||
|
||||
var chart = new ApexCharts(document.querySelector('#chart'), options)
|
||||
chart.render()
|
||||
```
|
||||
|
||||
This will render the following chart
|
||||
|
||||
<p align="center"><a href="https://apexcharts.com/javascript-chart-demos/column-charts/"><img src="https://apexcharts.com/media/first-bar-chart.svg"></a></p>
|
||||
|
||||
### A little more than the basic
|
||||
|
||||
You can create a combination of different charts, sync them and give your desired look with unlimited possibilities.
|
||||
Below is an example of synchronized charts with github style.
|
||||
|
||||
<p align="center"><a href="https://apexcharts.com/javascript-chart-demos/area-charts/github-style/"><img src="https://apexcharts.com/media/github-charts.gif"></a></p>
|
||||
|
||||
## Interactivity
|
||||
|
||||
Zoom, Pan, and Scroll through data. Make selections and load other charts using those selections.
|
||||
An example showing some interactivity
|
||||
|
||||
<p align="center"><a href="https://codepen.io/apexcharts/pen/QrbEQg" target="_blank"><img src="https://apexcharts.com/media/interactivity.gif" alt="interactive chart"></a></p>
|
||||
|
||||
## Dynamic Series Update
|
||||
|
||||
Another approach is to Drill down charts where one selection updates the data of other charts.
|
||||
An example of loading dynamic series into charts is shown below
|
||||
|
||||
<p align="center"><a href="https://apexcharts.com/javascript-chart-demos/column-charts/dynamic-loaded-chart/"><img src="https://apexcharts.com/media/dynamic-selection.gif" alt="dynamic-loading-chart" /></a></p>
|
||||
|
||||
## Annotations
|
||||
|
||||
Annotations allow you to write custom text on specific values or on axes values. Valuable to expand the visual appeal of your chart and make it more informative.
|
||||
|
||||
<p align="center"><a href="https://apexcharts.com/docs/annotations/"><img src="https://apexcharts.com/media/annotations.png" alt="annotations" /></a></p>
|
||||
|
||||
## Mixed Charts
|
||||
|
||||
You can combine more than one chart type to create a combo/mixed chart. Possible combinations can be line/area/column together in a single chart. Each chart type can have its own y-axis.
|
||||
|
||||
<p align="center"><a href="https://apexcharts.com/javascript-chart-demos/mixed-charts/"><img src="https://apexcharts.com/wp-content/uploads/2018/05/line-column-area-mixed-chart.svg" alt="annotations" width="490" /></a></p>
|
||||
|
||||
## Candlestick
|
||||
|
||||
Use a candlestick chart (a common financial chart) to describe price changes of a security, derivative, or currency. The below image shows how you can use another chart as a brush/preview pane which acts as a handle to browse the main candlestick chart.
|
||||
|
||||
<p align="center"><a href="https://apexcharts.com/javascript-chart-demos/candlestick-charts/"><img src="https://apexcharts.com/media/candlestick.png" alt="candlestick" width="490" /></a></p>
|
||||
|
||||
## Heatmaps
|
||||
|
||||
Use Heatmaps to represent data through colors and shades. Frequently used with bigger data collections, they are valuable for recognizing patterns and areas of focus.
|
||||
|
||||
<p align="center"><a href="https://apexcharts.com/javascript-chart-demos/heatmap-charts/"><img src="https://apexcharts.com/media/heatmap-charts.png" alt="heatmap" /></a></p>
|
||||
|
||||
## Gauges
|
||||
|
||||
The tiny gauges are an important part of a dashboard and are useful in displaying single-series data. A demo of these gauges:
|
||||
|
||||
<p align="center"><a href="https://apexcharts.com/javascript-chart-demos/radialbar-charts/"><img src="https://apexcharts.com/media/radialbars-gauges.png" width="490" alt="radialbar-chart" /></a></p>
|
||||
|
||||
## Sparklines
|
||||
|
||||
Utilize sparklines to indicate trends in data, for example, occasional increments or declines, monetary cycles, or to feature the most extreme and least values:
|
||||
|
||||
<p align="center"><a href="https://apexcharts.com/javascript-chart-demos/sparklines/"><img src="https://apexcharts.com/media/sparklines.png" alt="sparkline-chart" /></a></p>
|
||||
|
||||
|
||||
## Need Advanced Data Grid for your next project?
|
||||
We partnered with Infragistics, creators of the fastest data grids on the planet! Ignite UI Grids can handle unlimited rows and columns of data while providing access to custom templates and real-time data updates.
|
||||
|
||||
<p align="center"><a href="https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/grid" target="_blank"><img src="https://apexcharts.com/media/infragistics-data-grid.png" /></a></p>
|
||||
|
||||
Featuring an intuitive API for easy theming and branding, you can quickly bind to data with minimal hand-on coding. The grid is available in most of your favorite frameworks:
|
||||
|
||||
<a target="_blank" href="https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/grid">Angular Data Grid</a> | <a target="_blank" href="https://www.infragistics.com/products/ignite-ui-react/react/components/grids">React Data Grid</a> | <a target="_blank" href="https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/data-grid">Blazor Data Grid</a> | <a target="_blank" href="https://www.infragistics.com/products/ignite-ui-web-components/web-components/components/data-grid">Web Components DataGrid</a> | <a target="_blank" href="https://www.igniteui.com/grid/overview">jQuery Data Grid </a>
|
||||
|
||||
## What's included
|
||||
|
||||
The download bundle includes the following files and directories providing a minified single file in the dist folder. Every asset including icon/css is bundled in the js itself to avoid loading multiple files.
|
||||
|
||||
```
|
||||
apexcharts/
|
||||
├── dist/
|
||||
│ └── apexcharts.min.js
|
||||
├── src/
|
||||
│ ├── assets/
|
||||
│ ├── charts/
|
||||
│ ├── modules/
|
||||
│ ├── utils/
|
||||
│ └── apexcharts.js
|
||||
└── samples/
|
||||
```
|
||||
|
||||
## Using it with IE11
|
||||
|
||||
If you need to make it work with IE11, you need to include these polyfills before including ApexCharts
|
||||
|
||||
- [promise-polyfill](https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js)
|
||||
- [classlist.js](https://cdn.jsdelivr.net/npm/eligrey-classlist-js-polyfill)
|
||||
- [ResizeObserver polyfill](https://cdn.jsdelivr.net/npm/@juggle/resize-observer)
|
||||
- [findIndex](https://cdn.jsdelivr.net/npm/findindex_polyfill_mdn) - You will need this only if you require timeline/rangebar charts
|
||||
- [canvg](https://unpkg.com/canvg@3.0.4/lib/umd.js) - You will need this only if you require PNG download of your charts
|
||||
|
||||
## Development
|
||||
|
||||
#### Install dependencies and run the project
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
This will start the webpack watch and any changes you make to `src` folder will auto-compile and output will be produced in the `dist` folder.
|
||||
|
||||
More details in [Contributing Guidelines](CONTRIBUTING.md).
|
||||
|
||||
#### Minifying the src
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Where do I go next?
|
||||
|
||||
Head over to the <a href="https://apexcharts.com/docs/">documentation</a> section to read more about how to use different kinds of charts and explore all options.
|
||||
|
||||
## Contacts
|
||||
|
||||
Email: <a href="info@apexcharts.com">info@apexcharts.com</a>
|
||||
|
||||
Twitter: <a href="https://twitter.com/apexcharts">@apexcharts</a>
|
||||
|
||||
Facebook: <a href="https://facebook.com/apexcharts">fb.com/apexcharts</a>
|
||||
|
||||
## Dependency
|
||||
|
||||
ApexCharts uses <a href="https://svgdotjs.github.io/" target="_blank">SVG.js</a> for drawing shapes, animations, applying svg filters, and a lot more under the hood. The library is bundled in the final build file, so you don't need to include it.
|
||||
|
||||
## License
|
||||
|
||||
ApexCharts is released under MIT license. You are free to use, modify and distribute this software, as long as the copyright header is left intact.
|
||||
@@ -1,601 +0,0 @@
|
||||
@keyframes opaque {
|
||||
0% {
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes resizeanim {
|
||||
0%,to {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
|
||||
.apexcharts-canvas {
|
||||
position: relative;
|
||||
user-select: none
|
||||
}
|
||||
|
||||
.apexcharts-canvas ::-webkit-scrollbar {
|
||||
-webkit-appearance: none;
|
||||
width: 6px
|
||||
}
|
||||
|
||||
.apexcharts-canvas ::-webkit-scrollbar-thumb {
|
||||
border-radius: 4px;
|
||||
background-color: rgba(0,0,0,.5);
|
||||
box-shadow: 0 0 1px rgba(255,255,255,.5);
|
||||
-webkit-box-shadow: 0 0 1px rgba(255,255,255,.5)
|
||||
}
|
||||
|
||||
.apexcharts-inner {
|
||||
position: relative
|
||||
}
|
||||
|
||||
.apexcharts-text tspan {
|
||||
font-family: inherit
|
||||
}
|
||||
|
||||
.legend-mouseover-inactive {
|
||||
transition: .15s ease all;
|
||||
opacity: .2
|
||||
}
|
||||
|
||||
.apexcharts-legend-text {
|
||||
padding-left: 15px;
|
||||
margin-left: -15px;
|
||||
}
|
||||
|
||||
.apexcharts-series-collapsed {
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
.apexcharts-tooltip {
|
||||
border-radius: 5px;
|
||||
box-shadow: 2px 2px 6px -4px #999;
|
||||
cursor: default;
|
||||
font-size: 14px;
|
||||
left: 62px;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
z-index: 12;
|
||||
transition: .15s ease all
|
||||
}
|
||||
|
||||
.apexcharts-tooltip.apexcharts-active {
|
||||
opacity: 1;
|
||||
transition: .15s ease all
|
||||
}
|
||||
|
||||
.apexcharts-tooltip.apexcharts-theme-light {
|
||||
border: 1px solid #e3e3e3;
|
||||
background: rgba(255,255,255,.96)
|
||||
}
|
||||
|
||||
.apexcharts-tooltip.apexcharts-theme-dark {
|
||||
color: #fff;
|
||||
background: rgba(30,30,30,.8)
|
||||
}
|
||||
|
||||
.apexcharts-tooltip * {
|
||||
font-family: inherit
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-title {
|
||||
padding: 6px;
|
||||
font-size: 15px;
|
||||
margin-bottom: 4px
|
||||
}
|
||||
|
||||
.apexcharts-tooltip.apexcharts-theme-light .apexcharts-tooltip-title {
|
||||
background: #eceff1;
|
||||
border-bottom: 1px solid #ddd
|
||||
}
|
||||
|
||||
.apexcharts-tooltip.apexcharts-theme-dark .apexcharts-tooltip-title {
|
||||
background: rgba(0,0,0,.7);
|
||||
border-bottom: 1px solid #333
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-text-goals-value,.apexcharts-tooltip-text-y-value,.apexcharts-tooltip-text-z-value {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
font-weight: 600
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-text-goals-label:empty,.apexcharts-tooltip-text-goals-value:empty,.apexcharts-tooltip-text-y-label:empty,.apexcharts-tooltip-text-y-value:empty,.apexcharts-tooltip-text-z-value:empty,.apexcharts-tooltip-title:empty {
|
||||
display: none
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-text-goals-label,.apexcharts-tooltip-text-goals-value {
|
||||
padding: 6px 0 5px
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-goals-group,.apexcharts-tooltip-text-goals-label,.apexcharts-tooltip-text-goals-value {
|
||||
display: flex
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-text-goals-label:not(:empty),.apexcharts-tooltip-text-goals-value:not(:empty) {
|
||||
margin-top: -6px
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-marker {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
position: relative;
|
||||
top: 0;
|
||||
margin-right: 10px;
|
||||
border-radius: 50%
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-series-group {
|
||||
padding: 0 10px;
|
||||
display: none;
|
||||
text-align: left;
|
||||
justify-content: left;
|
||||
align-items: center
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-series-group.apexcharts-active .apexcharts-tooltip-marker {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-series-group.apexcharts-active,.apexcharts-tooltip-series-group:last-child {
|
||||
padding-bottom: 4px
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-series-group-hidden {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
line-height: 0;
|
||||
padding: 0!important
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-y-group {
|
||||
padding: 6px 0 5px
|
||||
}
|
||||
|
||||
.apexcharts-custom-tooltip,.apexcharts-tooltip-box {
|
||||
padding: 4px 8px
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-boxPlot {
|
||||
display: flex;
|
||||
flex-direction: column-reverse
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-box>div {
|
||||
margin: 4px 0
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-box span.value {
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-rangebar {
|
||||
padding: 5px 8px
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-rangebar .category {
|
||||
font-weight: 600;
|
||||
color: #777
|
||||
}
|
||||
|
||||
.apexcharts-tooltip-rangebar .series-name {
|
||||
font-weight: 700;
|
||||
display: block;
|
||||
margin-bottom: 5px
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip,.apexcharts-yaxistooltip {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
color: #373d3f;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background: #eceff1;
|
||||
border: 1px solid #90a4ae
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip {
|
||||
padding: 9px 10px;
|
||||
transition: .15s ease all
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip.apexcharts-theme-dark {
|
||||
background: rgba(0,0,0,.7);
|
||||
border: 1px solid rgba(0,0,0,.5);
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip:after,.apexcharts-xaxistooltip:before {
|
||||
left: 50%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip:after {
|
||||
border-color: transparent;
|
||||
border-width: 6px;
|
||||
margin-left: -6px
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip:before {
|
||||
border-color: transparent;
|
||||
border-width: 7px;
|
||||
margin-left: -7px
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip-bottom:after,.apexcharts-xaxistooltip-bottom:before {
|
||||
bottom: 100%
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip-top:after,.apexcharts-xaxistooltip-top:before {
|
||||
top: 100%
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip-bottom:after {
|
||||
border-bottom-color: #eceff1
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip-bottom:before {
|
||||
border-bottom-color: #90a4ae
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:after,.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:before {
|
||||
border-bottom-color: rgba(0,0,0,.5)
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip-top:after {
|
||||
border-top-color: #eceff1
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip-top:before {
|
||||
border-top-color: #90a4ae
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip-top.apexcharts-theme-dark:after,.apexcharts-xaxistooltip-top.apexcharts-theme-dark:before {
|
||||
border-top-color: rgba(0,0,0,.5)
|
||||
}
|
||||
|
||||
.apexcharts-xaxistooltip.apexcharts-active {
|
||||
opacity: 1;
|
||||
transition: .15s ease all
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip {
|
||||
padding: 4px 10px
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip.apexcharts-theme-dark {
|
||||
background: rgba(0,0,0,.7);
|
||||
border: 1px solid rgba(0,0,0,.5);
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip:after,.apexcharts-yaxistooltip:before {
|
||||
top: 50%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip:after {
|
||||
border-color: transparent;
|
||||
border-width: 6px;
|
||||
margin-top: -6px
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip:before {
|
||||
border-color: transparent;
|
||||
border-width: 7px;
|
||||
margin-top: -7px
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip-left:after,.apexcharts-yaxistooltip-left:before {
|
||||
left: 100%
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip-right:after,.apexcharts-yaxistooltip-right:before {
|
||||
right: 100%
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip-left:after {
|
||||
border-left-color: #eceff1
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip-left:before {
|
||||
border-left-color: #90a4ae
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip-left.apexcharts-theme-dark:after,.apexcharts-yaxistooltip-left.apexcharts-theme-dark:before {
|
||||
border-left-color: rgba(0,0,0,.5)
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip-right:after {
|
||||
border-right-color: #eceff1
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip-right:before {
|
||||
border-right-color: #90a4ae
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip-right.apexcharts-theme-dark:after,.apexcharts-yaxistooltip-right.apexcharts-theme-dark:before {
|
||||
border-right-color: rgba(0,0,0,.5)
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip.apexcharts-active {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
.apexcharts-yaxistooltip-hidden {
|
||||
display: none
|
||||
}
|
||||
|
||||
.apexcharts-xcrosshairs,.apexcharts-ycrosshairs {
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: .15s ease all
|
||||
}
|
||||
|
||||
.apexcharts-xcrosshairs.apexcharts-active,.apexcharts-ycrosshairs.apexcharts-active {
|
||||
opacity: 1;
|
||||
transition: .15s ease all
|
||||
}
|
||||
|
||||
.apexcharts-ycrosshairs-hidden {
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
.apexcharts-selection-rect {
|
||||
cursor: move
|
||||
}
|
||||
|
||||
.svg_select_boundingRect,.svg_select_points_rot {
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
visibility: hidden
|
||||
}
|
||||
|
||||
.apexcharts-selection-rect+g .svg_select_boundingRect,.apexcharts-selection-rect+g .svg_select_points_rot {
|
||||
opacity: 0;
|
||||
visibility: hidden
|
||||
}
|
||||
|
||||
.apexcharts-selection-rect+g .svg_select_points_l,.apexcharts-selection-rect+g .svg_select_points_r {
|
||||
cursor: ew-resize;
|
||||
opacity: 1;
|
||||
visibility: visible
|
||||
}
|
||||
|
||||
.svg_select_points {
|
||||
fill: #efefef;
|
||||
stroke: #333;
|
||||
rx: 2
|
||||
}
|
||||
|
||||
.apexcharts-svg.apexcharts-zoomable.hovering-zoom {
|
||||
cursor: crosshair
|
||||
}
|
||||
|
||||
.apexcharts-svg.apexcharts-zoomable.hovering-pan {
|
||||
cursor: move
|
||||
}
|
||||
|
||||
.apexcharts-menu-icon,.apexcharts-pan-icon,.apexcharts-reset-icon,.apexcharts-selection-icon,.apexcharts-toolbar-custom-icon,.apexcharts-zoom-icon,.apexcharts-zoomin-icon,.apexcharts-zoomout-icon {
|
||||
cursor: pointer;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 24px;
|
||||
color: #6e8192;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.apexcharts-menu-icon svg,.apexcharts-reset-icon svg,.apexcharts-zoom-icon svg,.apexcharts-zoomin-icon svg,.apexcharts-zoomout-icon svg {
|
||||
fill: #6e8192
|
||||
}
|
||||
|
||||
.apexcharts-selection-icon svg {
|
||||
fill: #444;
|
||||
transform: scale(.76)
|
||||
}
|
||||
|
||||
.apexcharts-theme-dark .apexcharts-menu-icon svg,.apexcharts-theme-dark .apexcharts-pan-icon svg,.apexcharts-theme-dark .apexcharts-reset-icon svg,.apexcharts-theme-dark .apexcharts-selection-icon svg,.apexcharts-theme-dark .apexcharts-toolbar-custom-icon svg,.apexcharts-theme-dark .apexcharts-zoom-icon svg,.apexcharts-theme-dark .apexcharts-zoomin-icon svg,.apexcharts-theme-dark .apexcharts-zoomout-icon svg {
|
||||
fill: #f3f4f5
|
||||
}
|
||||
|
||||
.apexcharts-canvas .apexcharts-reset-zoom-icon.apexcharts-selected svg,.apexcharts-canvas .apexcharts-selection-icon.apexcharts-selected svg,.apexcharts-canvas .apexcharts-zoom-icon.apexcharts-selected svg {
|
||||
fill: #008ffb
|
||||
}
|
||||
|
||||
.apexcharts-theme-light .apexcharts-menu-icon:hover svg,.apexcharts-theme-light .apexcharts-reset-icon:hover svg,.apexcharts-theme-light .apexcharts-selection-icon:not(.apexcharts-selected):hover svg,.apexcharts-theme-light .apexcharts-zoom-icon:not(.apexcharts-selected):hover svg,.apexcharts-theme-light .apexcharts-zoomin-icon:hover svg,.apexcharts-theme-light .apexcharts-zoomout-icon:hover svg {
|
||||
fill: #333
|
||||
}
|
||||
|
||||
.apexcharts-menu-icon,.apexcharts-selection-icon {
|
||||
position: relative
|
||||
}
|
||||
|
||||
.apexcharts-reset-icon {
|
||||
margin-left: 5px
|
||||
}
|
||||
|
||||
.apexcharts-menu-icon,.apexcharts-reset-icon,.apexcharts-zoom-icon {
|
||||
transform: scale(.85)
|
||||
}
|
||||
|
||||
.apexcharts-zoomin-icon,.apexcharts-zoomout-icon {
|
||||
transform: scale(.7)
|
||||
}
|
||||
|
||||
.apexcharts-zoomout-icon {
|
||||
margin-right: 3px
|
||||
}
|
||||
|
||||
.apexcharts-pan-icon {
|
||||
transform: scale(.62);
|
||||
position: relative;
|
||||
left: 1px;
|
||||
top: 0
|
||||
}
|
||||
|
||||
.apexcharts-pan-icon svg {
|
||||
fill: #fff;
|
||||
stroke: #6e8192;
|
||||
stroke-width: 2
|
||||
}
|
||||
|
||||
.apexcharts-pan-icon.apexcharts-selected svg {
|
||||
stroke: #008ffb
|
||||
}
|
||||
|
||||
.apexcharts-pan-icon:not(.apexcharts-selected):hover svg {
|
||||
stroke: #333
|
||||
}
|
||||
|
||||
.apexcharts-toolbar {
|
||||
position: absolute;
|
||||
z-index: 11;
|
||||
max-width: 176px;
|
||||
text-align: right;
|
||||
border-radius: 3px;
|
||||
padding: 0 6px 2px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center
|
||||
}
|
||||
|
||||
.apexcharts-menu {
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
padding: 3px;
|
||||
right: 10px;
|
||||
opacity: 0;
|
||||
min-width: 110px;
|
||||
transition: .15s ease all;
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.apexcharts-menu.apexcharts-menu-open {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
transition: .15s ease all
|
||||
}
|
||||
|
||||
.apexcharts-menu-item {
|
||||
padding: 6px 7px;
|
||||
font-size: 12px;
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.apexcharts-theme-light .apexcharts-menu-item:hover {
|
||||
background: #eee
|
||||
}
|
||||
|
||||
.apexcharts-theme-dark .apexcharts-menu {
|
||||
background: rgba(0,0,0,.7);
|
||||
color: #fff
|
||||
}
|
||||
|
||||
@media screen and (min-width:768px) {
|
||||
.apexcharts-canvas:hover .apexcharts-toolbar {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
|
||||
.apexcharts-canvas .apexcharts-element-hidden,.apexcharts-datalabel.apexcharts-element-hidden,.apexcharts-hide .apexcharts-series-points {
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
.apexcharts-hidden-element-shown {
|
||||
opacity: 1;
|
||||
transition: 0.25s ease all;
|
||||
}
|
||||
.apexcharts-datalabel,.apexcharts-datalabel-label,.apexcharts-datalabel-value,.apexcharts-datalabels,.apexcharts-pie-label {
|
||||
cursor: default;
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.apexcharts-pie-label-delay {
|
||||
opacity: 0;
|
||||
animation-name: opaque;
|
||||
animation-duration: .3s;
|
||||
animation-fill-mode: forwards;
|
||||
animation-timing-function: ease
|
||||
}
|
||||
|
||||
.apexcharts-radialbar-label {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.apexcharts-annotation-rect,.apexcharts-area-series .apexcharts-area,.apexcharts-area-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,.apexcharts-gridline,.apexcharts-line,.apexcharts-line-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,.apexcharts-point-annotation-label,.apexcharts-radar-series path,.apexcharts-radar-series polygon,.apexcharts-toolbar svg,.apexcharts-tooltip .apexcharts-marker,.apexcharts-xaxis-annotation-label,.apexcharts-yaxis-annotation-label,.apexcharts-zoom-rect {
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.apexcharts-marker {
|
||||
transition: .15s ease all
|
||||
}
|
||||
|
||||
.resize-triggers {
|
||||
animation: 1ms resizeanim;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.contract-trigger:before,.resize-triggers,.resize-triggers>div {
|
||||
content: " ";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0
|
||||
}
|
||||
|
||||
.resize-triggers>div {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: #eee;
|
||||
overflow: auto
|
||||
}
|
||||
|
||||
.contract-trigger:before {
|
||||
overflow: hidden;
|
||||
width: 200%;
|
||||
height: 200%
|
||||
}
|
||||
|
||||
.apexcharts-bar-goals-markers{
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.apexcharts-bar-shadows{
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.apexcharts-rangebar-goals-markers{
|
||||
pointer-events: none
|
||||
}
|
||||