Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
a5168a282b
|
|||
| 4219570d80 | |||
| 710a08c868 | |||
| 2f6dcf13f7 | |||
| 8dec47ff63 | |||
|
9e68d73cf4
|
|||
|
65783c1ca0
|
|||
|
8c070fd616
|
|||
|
95995d0a4e
|
|||
|
72c1968c67
|
|||
| 000ae78d1e | |||
|
f4ac9a4f15
|
|||
|
7c7d8a6c3a
|
|||
|
0fe8077f7e
|
|||
|
a3ab6731c6
|
|||
| c7697a4b3c | |||
|
7994f2768d
|
|||
|
bb15fe9b7a
|
|||
|
785eb9e66a
|
|||
|
7590e81f5c
|
|||
| 8ba3d6e093 | |||
| 88cd92a159 | |||
| 9c5a000555 | |||
| 130cada092 | |||
| 7f6e377674 | |||
| fe06abadcf | |||
| 00eab70d71 | |||
| 2e74a8b762 | |||
| e3f2d4fd0a | |||
| 6c0b39ddbf | |||
|
b14c132808
|
|||
| a7b5c24d72 | |||
|
2556843ef6
|
|||
| 43f4a8f9ce | |||
| 9abd6c554a | |||
| 1005852091 | |||
|
61a36fc2bc
|
|||
|
714ece9637
|
|||
|
b2ba415373
|
@@ -11,6 +11,7 @@ node_modules
|
|||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
|||||||
Generated
+107
-2
@@ -8,10 +8,13 @@
|
|||||||
"name": "drive-thru",
|
"name": "drive-thru",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "^2.6.0",
|
||||||
"@tailwindcss/vite": "^4.0.9",
|
"@tailwindcss/vite": "^4.0.9",
|
||||||
|
"lucide-react": "^0.476.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
|
"react-redux": "^9.2.0",
|
||||||
"react-router-dom": "^7.2.0"
|
"react-router-dom": "^7.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -921,6 +924,30 @@
|
|||||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@reduxjs/toolkit": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-SSlIqZNYhqm/oMkXbtofwZSt9lrncblzo6YcZ9zoX+zLngRBrCOjK4lNLdkNucJF58RHOWrD9txT3bT3piH7Zw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"immer": "^10.0.3",
|
||||||
|
"redux": "^5.0.1",
|
||||||
|
"redux-thunk": "^3.1.0",
|
||||||
|
"reselect": "^5.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
|
||||||
|
"react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-redux": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.34.8",
|
"version": "4.34.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
|
||||||
@@ -1420,7 +1447,7 @@
|
|||||||
"version": "19.0.10",
|
"version": "19.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz",
|
||||||
"integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==",
|
"integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
@@ -1434,6 +1461,12 @@
|
|||||||
"@types/react": "^19.0.0"
|
"@types/react": "^19.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/use-sync-external-store": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@vitejs/plugin-react": {
|
"node_modules/@vitejs/plugin-react": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",
|
||||||
@@ -1897,7 +1930,7 @@
|
|||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/data-view-buffer": {
|
"node_modules/data-view-buffer": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@@ -2847,6 +2880,16 @@
|
|||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immer": {
|
||||||
|
"version": "10.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz",
|
||||||
|
"integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/immer"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
||||||
@@ -3624,6 +3667,15 @@
|
|||||||
"yallist": "^3.0.2"
|
"yallist": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lucide-react": {
|
||||||
|
"version": "0.476.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.476.0.tgz",
|
||||||
|
"integrity": "sha512-x6cLTk8gahdUPje0hSgLN1/MgiJH+Xl90Xoxy9bkPAsMPOUiyRSKR4JCDPGVCEpyqnZXH3exFWNItcvra9WzUQ==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/math-intrinsics": {
|
"node_modules/math-intrinsics": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
@@ -3998,6 +4050,29 @@
|
|||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/react-redux": {
|
||||||
|
"version": "9.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
||||||
|
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/use-sync-external-store": "^0.0.6",
|
||||||
|
"use-sync-external-store": "^1.4.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^18.2.25 || ^19",
|
||||||
|
"react": "^18.0 || ^19",
|
||||||
|
"redux": "^5.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"redux": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-refresh": {
|
"node_modules/react-refresh": {
|
||||||
"version": "0.14.2",
|
"version": "0.14.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
|
||||||
@@ -4045,6 +4120,21 @@
|
|||||||
"react-dom": ">=18"
|
"react-dom": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/redux": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/redux-thunk": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"redux": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reflect.getprototypeof": {
|
"node_modules/reflect.getprototypeof": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||||
@@ -4087,6 +4177,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/reselect": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "2.0.0-next.5",
|
"version": "2.0.0-next.5",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
|
||||||
@@ -4658,6 +4754,15 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/use-sync-external-store": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz",
|
||||||
|
|||||||
@@ -10,10 +10,13 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "^2.6.0",
|
||||||
"@tailwindcss/vite": "^4.0.9",
|
"@tailwindcss/vite": "^4.0.9",
|
||||||
|
"lucide-react": "^0.476.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
|
"react-redux": "^9.2.0",
|
||||||
"react-router-dom": "^7.2.0"
|
"react-router-dom": "^7.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 144 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
@@ -1,19 +1,20 @@
|
|||||||
import "./App.css";
|
import "./App.css";
|
||||||
import DrivethruLandingPage from "./pages/DrivethruLandingPage";
|
|
||||||
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
||||||
import Login from "./pages/Authentication/Login";
|
import Login from "./pages/Authentication/Login";
|
||||||
import SignUp from "./pages/Authentication/SignUp";
|
import SignUp from "./pages/Authentication/SignUp";
|
||||||
|
import DrivethruLandingPage from "./pages/UserPages/DrivethruLandingPage";
|
||||||
|
import Dashboard from "./pages/UserPages/Dashboard";
|
||||||
|
import NotFoundPage from "./pages/UserPages/NotFoundPage";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
<Routes>
|
<Routes>
|
||||||
{/* Landing Page at root ("/") */}
|
|
||||||
<Route path="/" element={<DrivethruLandingPage />} />
|
<Route path="/" element={<DrivethruLandingPage />} />
|
||||||
|
|
||||||
{/* Login Page at "/login" */}
|
|
||||||
<Route path="/login" element={<Login />} />
|
<Route path="/login" element={<Login />} />
|
||||||
<Route path="/signup" element={<SignUp />} />
|
<Route path="/signup" element={<SignUp />} />
|
||||||
|
<Route path="/Dashboard" element={<Dashboard />} />
|
||||||
|
<Route path="*" element={<NotFoundPage />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
|
const FileTable = ({ initialPath }) => {
|
||||||
|
const [currentPath, setCurrentPath] = useState(initialPath || "/");
|
||||||
|
const [files, setFiles] = useState([]);
|
||||||
|
|
||||||
|
// Helpers to parse entry
|
||||||
|
const getType = (entry) =>
|
||||||
|
entry.trim().startsWith("📁") ? "Folder" : "File";
|
||||||
|
const getName = (entry) => entry.trim().replace(/^📁\s*|^📄\s*/, "");
|
||||||
|
const isFile = (entry) => getType(entry) === "File";
|
||||||
|
|
||||||
|
// Fetch and show only top-level entries (indentation = 0)
|
||||||
|
const fetchFiles = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`http://192.168.29.61:8080/api/hdfs/listFiles?hdfsPath=${currentPath}`
|
||||||
|
);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
// Filter entries: only those without leading spaces
|
||||||
|
const filtered = data.filter(
|
||||||
|
(entry) => entry.match(/^ */)[0].length === 0
|
||||||
|
);
|
||||||
|
setFiles(filtered);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch files:", error);
|
||||||
|
setFiles([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchFiles();
|
||||||
|
}, [currentPath]);
|
||||||
|
|
||||||
|
// Navigate into a folder
|
||||||
|
const handleOpenFolder = (folderName) => {
|
||||||
|
const newPath =
|
||||||
|
currentPath === "/" ? `/${folderName}` : `${currentPath}/${folderName}`;
|
||||||
|
setCurrentPath(newPath);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Go up one level
|
||||||
|
const goBack = () => {
|
||||||
|
if (currentPath === "/") return;
|
||||||
|
const parts = currentPath.split("/").filter(Boolean);
|
||||||
|
parts.pop();
|
||||||
|
setCurrentPath(parts.length === 0 ? "/" : `/${parts.join("/")}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative overflow-x-auto shadow-md rounded-lg">
|
||||||
|
<div className="flex items-center justify-between px-6 py-4 bg-blue-100 text-black font-medium">
|
||||||
|
<span>Path: {currentPath}</span>
|
||||||
|
{currentPath !== "/" && (
|
||||||
|
<button onClick={goBack} className="text-blue-600 hover:underline">
|
||||||
|
⬅️ Go Back
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<table className="w-full text-sm text-left text-black">
|
||||||
|
<thead className="text-xs text-black uppercase bg-blue-100">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" className="px-6 py-3">
|
||||||
|
File Name
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3">
|
||||||
|
Type
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3">
|
||||||
|
Action
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{files.length === 0 ? (
|
||||||
|
<tr>
|
||||||
|
<td colSpan="3" className="px-6 py-4 text-gray-600">
|
||||||
|
No files found.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
files.map((entry, idx) => {
|
||||||
|
const name = getName(entry);
|
||||||
|
const type = getType(entry);
|
||||||
|
const encodedPath = encodeURIComponent(`${currentPath}/${name}`);
|
||||||
|
const downloadUrl = `http://192.168.29.61:8080/api/hdfs/downloadFile?hdfsPath=${encodedPath}&localPath=E:/testdownload/${name}&kalas=${
|
||||||
|
currentPath.split("/")[1] || "user"
|
||||||
|
}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr
|
||||||
|
key={idx}
|
||||||
|
className="even:bg-blue-50 odd:bg-white border-b border-blue-200"
|
||||||
|
>
|
||||||
|
<td className="px-6 py-4 font-medium whitespace-nowrap">
|
||||||
|
{name}
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4">{type}</td>
|
||||||
|
<td className="px-6 py-4">
|
||||||
|
{isFile(entry) ? (
|
||||||
|
<a
|
||||||
|
href={downloadUrl}
|
||||||
|
className="font-medium text-blue-600 hover:underline"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Download
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
onClick={() => handleOpenFolder(name)}
|
||||||
|
className="font-medium text-blue-600 hover:underline"
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
FileTable.propTypes = {
|
||||||
|
initialPath: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FileTable;
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { uploadFileToHDFS } from "../utils/api";
|
||||||
|
|
||||||
|
const FileUpload = () => {
|
||||||
|
const [file, setFile] = useState(null);
|
||||||
|
const [hdfsPath, setHdfsPath] = useState("/kalas");
|
||||||
|
const [uploadedFileName, setUploadedFileName] = useState("");
|
||||||
|
const [username, setUsername] = useState("kalas");
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!file || !uploadedFileName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uploadFileToHDFS(file, hdfsPath, uploadedFileName, username);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
className="p-5 py-16 border rounded shadow w-full max-w-md"
|
||||||
|
>
|
||||||
|
<h2 className="text-lg font-bold mb-2">Upload File Your File</h2>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
onChange={(e) => {
|
||||||
|
setFile(e.target.files[0]);
|
||||||
|
setUploadedFileName(e.target.files[0]?.name || "");
|
||||||
|
}}
|
||||||
|
className="mb-2"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* <input
|
||||||
|
type="text"
|
||||||
|
placeholder="HDFS Path"
|
||||||
|
value={hdfsPath}
|
||||||
|
onChange={(e) => setHdfsPath(e.target.value)}
|
||||||
|
className="border p-2 mb-2 w-full"
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
{/* <input
|
||||||
|
type="text"
|
||||||
|
placeholder="Uploaded File Name"
|
||||||
|
value={uploadedFileName}
|
||||||
|
onChange={(e) => setUploadedFileName(e.target.value)}
|
||||||
|
className="border p-2 mb-2 w-full"
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
{/* <input
|
||||||
|
type="text"
|
||||||
|
placeholder="Username"
|
||||||
|
value={username}
|
||||||
|
onChange={(e) => setUsername(e.target.value)}
|
||||||
|
className="border p-2 mb-2 w-full"
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="bg-blue-600 text-white px-4 py-2 rounded"
|
||||||
|
>
|
||||||
|
Upload File
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FileUpload;
|
||||||
@@ -1,29 +1,159 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import {
|
||||||
|
Facebook,
|
||||||
|
Twitter,
|
||||||
|
Instagram,
|
||||||
|
Linkedin,
|
||||||
|
Mail,
|
||||||
|
Phone,
|
||||||
|
MapPin,
|
||||||
|
} from "lucide-react";
|
||||||
|
|
||||||
const Footer = () => {
|
const Footer = () => {
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
|
||||||
|
//Currently storing user email in localstorage
|
||||||
|
const handleSubscribe = () => {
|
||||||
|
if (email.trim() !== "") {
|
||||||
|
localStorage.setItem("subscribedEmail", email);
|
||||||
|
alert("You have successfully subscribed!");
|
||||||
|
setEmail("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className="bg-gradient-to-r from-[#689adc] via-[#6da1e6] h-[353px] w-full pt-16 pb-8">
|
<footer className="bg-gradient-to-r from-[#4a7cbd] via-[#5b4fd3] to-[#9377ff] w-full pt-16 pb-8">
|
||||||
<div className="container mx-auto px-4">
|
<div className="container mx-auto px-6">
|
||||||
<div className="flex items-center justify-center mb-4">
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-8 mb-12">
|
||||||
<div className="text-cyan-400 mr-3">
|
<div className="space-y-4">
|
||||||
<svg
|
<div className="flex items-center">
|
||||||
className="w-12 h-12"
|
<div className="text-white mr-3">
|
||||||
viewBox="0 0 24 24"
|
<svg
|
||||||
fill="none"
|
className="w-10 h-10"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
viewBox="0 0 24 24"
|
||||||
>
|
fill="none"
|
||||||
<path
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
d="M12 2L2 12L12 22L22 12L12 2Z"
|
>
|
||||||
stroke="currentColor"
|
<path
|
||||||
strokeWidth="3"
|
d="M12 2L2 12L12 22L22 12L12 2Z"
|
||||||
fill="none"
|
stroke="currentColor"
|
||||||
/>
|
strokeWidth="3"
|
||||||
</svg>
|
fill="none"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h3 className="text-2xl font-bold text-white">Drive-thru</h3>
|
||||||
|
</div>
|
||||||
|
<p className="text-white/90">
|
||||||
|
Your secure cloud storage solution for all your digital needs.
|
||||||
|
</p>
|
||||||
|
<div className="flex space-x-4">
|
||||||
|
<a href="https://facebook.com" target="_blank" rel="noopener noreferrer">
|
||||||
|
<Facebook className="w-5 h-5 text-white cursor-pointer hover:text-cyan-200 transition-all duration-200 transform hover:scale-110" />
|
||||||
|
</a>
|
||||||
|
<a href="https://twitter.com" target="_blank" rel="noopener noreferrer">
|
||||||
|
<Twitter className="w-5 h-5 text-white cursor-pointer hover:text-cyan-200 transition-all duration-200 transform hover:scale-110" />
|
||||||
|
</a>
|
||||||
|
<a href="https://instagram.com" target="_blank" rel="noopener noreferrer">
|
||||||
|
<Instagram className="w-5 h-5 text-white cursor-pointer hover:text-cyan-200 transition-all duration-200 transform hover:scale-110" />
|
||||||
|
</a>
|
||||||
|
<a href="https://linkedin.com" target="_blank" rel="noopener noreferrer">
|
||||||
|
<Linkedin className="w-5 h-5 text-white cursor-pointer hover:text-cyan-200 transition-all duration-200 transform hover:scale-110" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Quick Links */}
|
||||||
|
<div>
|
||||||
|
<h4 className="font-semibold text-white mb-4">Quick Links</h4>
|
||||||
|
<ul className="space-y-2">
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#about"
|
||||||
|
className="text-white/90 hover:text-white transition-all duration-200 hover:translate-x-1 inline-block"
|
||||||
|
>
|
||||||
|
About Us
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#features"
|
||||||
|
className="text-white/90 hover:text-white transition-all duration-200 hover:translate-x-1 inline-block"
|
||||||
|
>
|
||||||
|
Features
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#howItWorks"
|
||||||
|
className="text-white/90 hover:text-white transition-all duration-200 hover:translate-x-1 inline-block"
|
||||||
|
>
|
||||||
|
How It Works
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Contact Info */}
|
||||||
|
<div>
|
||||||
|
<h4 className="font-semibold text-white mb-4">Contact</h4>
|
||||||
|
<ul className="space-y-2">
|
||||||
|
<li className="flex items-center text-white/90 hover:text-white group transition-colors duration-200">
|
||||||
|
<Mail className="w-4 h-4 mr-2 group-hover:text-cyan-200" />
|
||||||
|
support@drivethru.com
|
||||||
|
</li>
|
||||||
|
<li className="flex items-center text-white/90 hover:text-white group transition-colors duration-200">
|
||||||
|
<Phone className="w-4 h-4 mr-2 group-hover:text-cyan-200" />
|
||||||
|
+91 3628206234
|
||||||
|
</li>
|
||||||
|
<li className="flex items-center text-white/90 hover:text-white group transition-colors duration-200">
|
||||||
|
<MapPin className="w-4 h-4 mr-2 group-hover:text-cyan-200" />
|
||||||
|
123 Cloud Street, Digital City
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Newsletter */}
|
||||||
|
<div>
|
||||||
|
<h4 className="font-semibold text-white mb-4">Stay Updated</h4>
|
||||||
|
<p className="text-white/90 mb-4">
|
||||||
|
Get exclusive tips, updates on new features, and special offers directly in your inbox.
|
||||||
|
</p>
|
||||||
|
<div className="space-y-4">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
placeholder="Enter your email"
|
||||||
|
className="w-full px-4 py-2 rounded-md bg-white/10 border border-white/20 text-white placeholder:text-white/50 focus:bg-white/20 transition-all duration-200 outline-none focus:ring-2 focus:ring-white/30"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={handleSubscribe}
|
||||||
|
className="w-full px-4 py-2 rounded-md bg-white text-blue-600 font-medium hover:bg-opacity-90 transition-all duration-200 transform hover:scale-105"
|
||||||
|
>
|
||||||
|
Subscribe to Newsletter
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="h-px w-full bg-white/20 my-8" />
|
||||||
|
|
||||||
|
{/* Bottom Section */}
|
||||||
|
<div className="flex flex-col md:flex-row justify-between items-center text-white/90 text-sm">
|
||||||
|
<p>© {new Date().getFullYear()} Drive-Thru. All rights reserved.</p>
|
||||||
|
<div className="flex gap-4 mt-4 md:mt-0">
|
||||||
|
<a href="#" className="hover:text-white transition-all duration-200 hover:translate-x-1 inline-block">
|
||||||
|
Privacy Policy
|
||||||
|
</a>
|
||||||
|
<a href="#" className="hover:text-white transition-all duration-200 hover:translate-x-1 inline-block">
|
||||||
|
Terms of Service
|
||||||
|
</a>
|
||||||
|
<a href="#" className="hover:text-white transition-all duration-200 hover:translate-x-1 inline-block">
|
||||||
|
Cookie Policy
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-5xl font-bold text-black">Drive-thru</h1>
|
|
||||||
</div>
|
</div>
|
||||||
<p className="text-black text-center">
|
|
||||||
About | Privacy Policy | Terms of Service | Contact@
|
|
||||||
{new Date().getFullYear()} Drive-Thru. All rights reserved.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,308 @@
|
|||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
const Sidebar = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<nav className="fixed top-0 z-50 h-[60px] w-full bg-white border-b border-gray-200 ">
|
||||||
|
<div className="p-[15px] h-full lg:px-5 lg:pl-3 ">
|
||||||
|
<div className="flex h-full items-center justify-between">
|
||||||
|
<div className="flex items-center justify-start rtl:justify-end">
|
||||||
|
<button
|
||||||
|
data-drawer-target="logo-sidebar"
|
||||||
|
data-drawer-toggle="logo-sidebar"
|
||||||
|
aria-controls="logo-sidebar"
|
||||||
|
type="button"
|
||||||
|
className="inline-flex items-center p-2 text-lg text-white rounded-lg sm:hidden hover:bg-[#37A0EA] focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-[#37A0EA] dark:focus:ring-gray-600"
|
||||||
|
>
|
||||||
|
<span className="sr-only">Open sidebar</span>
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6"
|
||||||
|
aria-hidden="true"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
clipRule="evenodd"
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M2 4.75A.75.75 0 012.75 4h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 4.75zm0 10.5a.75.75 0 01.75-.75h7.5a.75.75 0 010 1.5h-7.5a.75.75 0 01-.75-.75zM2 10a.75.75 0 01.75-.75h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 10z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<Link to="/" className="flex ms-2 md:me-24">
|
||||||
|
<img
|
||||||
|
src="./image.png"
|
||||||
|
className="h-8 me-3"
|
||||||
|
alt="Drive-thru Logo"
|
||||||
|
/>
|
||||||
|
<span className="self-center text-xl font-semibold sm:text-2xl whitespace-nowrap dark:text-white">
|
||||||
|
Drive-thru
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center">
|
||||||
|
{" "}
|
||||||
|
<div className="flex items-center justify-end mr-40 ">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Search..."
|
||||||
|
className="w-full border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="ml-2 px-4 py-2 text-white bg-blue-500 rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
>
|
||||||
|
Search
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center ms-3">
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex text-lg bg-gray-800 rounded-full focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600"
|
||||||
|
aria-expanded="false"
|
||||||
|
data-dropdown-toggle="dropdown-user"
|
||||||
|
>
|
||||||
|
<span className="sr-only">Open user menu</span>
|
||||||
|
<img
|
||||||
|
className="w-8 h-8 rounded-full"
|
||||||
|
src="https://flowbite.com/docs/images/people/profile-picture-5.jpg"
|
||||||
|
alt="user photo"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="z-50 hidden my-4 text-base list-none bg-[#1877F2] divide-y divide-gray-100 rounded-sm shadow-sm dark:bg-gray-700 dark:divide-gray-600"
|
||||||
|
id="dropdown-user"
|
||||||
|
>
|
||||||
|
<div className="px-4 py-3" role="none">
|
||||||
|
<p
|
||||||
|
className="text-lg text-white dark:text-white"
|
||||||
|
role="none"
|
||||||
|
>
|
||||||
|
Neil Sims
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
className="text-lg font-medium text-white truncate dark:text-gray-300"
|
||||||
|
role="none"
|
||||||
|
>
|
||||||
|
Drive-thru@Drive-thru.com
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<ul className="py-1" role="none">
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
to="#"
|
||||||
|
className="block px-4 py-2 text-lg text-white hover:bg-[#37A0EA] dark:text-gray-300 dark:hover:bg-[#37A0EA] dark:hover:text-white"
|
||||||
|
role="menuitem"
|
||||||
|
>
|
||||||
|
Dashboard
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
to="#"
|
||||||
|
className="block px-4 py-2 text-lg text-white hover:bg-[#37A0EA] dark:text-gray-300 dark:hover:bg-[##37A0EA] dark:hover:text-white"
|
||||||
|
role="menuitem"
|
||||||
|
>
|
||||||
|
Settings
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
to="#"
|
||||||
|
className="block px-4 py-2 text-lg text-white hover:bg-[#37A0EA] dark:text-gray-300 dark:hover:bg-[#37A0EA] dark:hover:text-white"
|
||||||
|
role="menuitem"
|
||||||
|
>
|
||||||
|
Earnings
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
to="#"
|
||||||
|
className="block px-4 py-2 text-lg text-white hover:bg-[#37A0EA] dark:text-gray-300 dark:hover:bg-[#37A0EA] dark:hover:text-white"
|
||||||
|
role="menuitem"
|
||||||
|
>
|
||||||
|
Sign out
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<aside
|
||||||
|
id="logo-sidebar"
|
||||||
|
className="fixed top-0 left-0 z-40 w-64 h-screen pt-[60px] transition-transform -translate-x-full bg-[##1877F2] border-r border-gray-200 sm:translate-x-0 dark:bg-[#1877F2] dark:border-gray-700"
|
||||||
|
aria-label="Sidebar"
|
||||||
|
>
|
||||||
|
<div className="h-full px-3 pb-4 overflow-y-auto bg-[#1877F2] dark:bg-[#1877F2] custom-scrollbar">
|
||||||
|
<ul className="space-y-2 font-medium">
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
to="#"
|
||||||
|
className="flex items-center p-2 mt-5 pt-4 pb-4 text-white rounded-lg dark:text-white hover:bg-[#37A0EA] dark:hover:bg-[#37A0EA] group"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="w-5 h-5 text-white transition duration-75 dark:text-gray-400 group-hover:text-white dark:group-hover:text-white"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.62L12 2 9.19 8.62 2 9.24l5.46 4.73L5.82 21z" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<span className="ms-3">Starred</span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
to="#"
|
||||||
|
className="flex items-center p-2 pt-4 pb-4 text-white rounded-lg dark:text-white hover:bg-[#37A0EA] dark:hover:bg-[#37A0EA] group"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="w-5 h-5"
|
||||||
|
viewBox="0 0 20 17"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M2.31763 16.0834C1.93846 16.0834 1.60669 15.9372 1.32231 15.6449C1.03794 15.3527 0.895752 15.0248 0.895752 14.6615V2.33856C0.895752 1.97519 1.03794 1.64737 1.32231 1.3551C1.60669 1.06282 1.93846 0.916687 2.31763 0.916687H8.97674L10.3986 2.33856H18.4322C18.7956 2.33856 19.1234 2.4847 19.4157 2.77697C19.7079 3.06925 19.8541 3.39707 19.8541 3.76044V14.6615C19.8541 15.0248 19.7079 15.3527 19.4157 15.6449C19.1234 15.9372 18.7956 16.0834 18.4322 16.0834H2.31763ZM9.4033 13.0026H16.9866V12.5524C16.9866 11.8888 16.6509 11.3477 15.9795 10.9291C15.308 10.5104 14.3799 10.3011 13.195 10.3011C12.0101 10.3011 11.0819 10.5104 10.4105 10.9291C9.73903 11.3477 9.4033 11.8888 9.4033 12.5524V13.0026ZM13.195 8.87919C13.6689 8.87919 14.0757 8.70935 14.4154 8.36968C14.7551 8.03001 14.9249 7.6232 14.9249 7.14924C14.9249 6.67528 14.7551 6.26847 14.4154 5.9288C14.0757 5.58913 13.6689 5.41929 13.195 5.41929C12.721 5.41929 12.3142 5.58913 11.9745 5.9288C11.6349 6.26847 11.465 6.67528 11.465 7.14924C11.465 7.6232 11.6349 8.03001 11.9745 8.36968C12.3142 8.70935 12.721 8.87919 13.195 8.87919Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<span className="flex-1 ms-3 whitespace-nowrap">
|
||||||
|
Shared with me
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
to="#"
|
||||||
|
className="flex items-center p-2 pt-4 pb-4 text-white rounded-lg dark:text-white hover:bg-[#37A0EA] dark:hover:bg-[#37A0EA] group"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="w-5 h-5"
|
||||||
|
fill="currentColor"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<path d="M5 3h2v18H5V3zm6 6h2v12h-2V9zm6-4h2v16h-2V5z" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<span className="flex-1 ms-3 whitespace-nowrap">
|
||||||
|
Statistics
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
to="#"
|
||||||
|
className="flex items-center p-2 pt-4 pb-4 text-white rounded-lg dark:text-white hover:bg-[#37A0EA] dark:hover:bg-[#37A0EA] group"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="w-5 h-5 text-white dark:text-white"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M3 6a2 2 0 0 1 2-2h5.532a2 2 0 0 1 1.536.72l1.9 2.28H3V6Zm0 3v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V9H3Z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<span className="flex-1 ms-3 whitespace-nowrap">My files</span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
to="#"
|
||||||
|
className="flex items-center p-2 pt-4 pb-4 text-white rounded-lg dark:text-white hover:bg-[#37A0EA] dark:hover:bg-[#37A0EA] group"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="w-5 h-5"
|
||||||
|
viewBox="0 0 20 19"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M8.19471 18.9791L7.72075 15.9932C7.42058 15.8826 7.10461 15.7325 6.77284 15.5429C6.44106 15.3534 6.14879 15.1559 5.89601 14.9505L3.09966 16.2302L0.895752 12.3437L3.45513 10.4716C3.42353 10.3294 3.40378 10.1675 3.39588 9.98579C3.38798 9.8041 3.38403 9.64217 3.38403 9.49998C3.38403 9.35779 3.38798 9.19586 3.39588 9.01417C3.40378 8.83249 3.42353 8.67055 3.45513 8.52837L0.895752 6.65623L3.09966 2.76977L5.89601 4.04946C6.14879 3.84408 6.44106 3.64659 6.77284 3.45701C7.10461 3.26743 7.42058 3.12524 7.72075 3.03045L8.19471 0.020813H12.5551L13.0291 3.00675C13.3293 3.11734 13.6492 3.26348 13.9889 3.44516C14.3285 3.62685 14.6168 3.82828 14.8538 4.04946L17.6502 2.76977L19.8541 6.65623L17.2947 8.48097C17.3263 8.63896 17.3461 8.80879 17.354 8.99048C17.3619 9.17216 17.3658 9.34199 17.3658 9.49998C17.3658 9.65797 17.3619 9.82385 17.354 9.99764C17.3461 10.1714 17.3263 10.3373 17.2947 10.4953L19.8541 12.3437L17.6502 16.2302L14.8538 14.9505C14.601 15.1559 14.3127 15.3573 13.9889 15.5548C13.665 15.7523 13.3451 15.8984 13.0291 15.9932L12.5551 18.9791H8.19471ZM10.3749 12.5807C11.228 12.5807 11.9548 12.2805 12.5551 11.6802C13.1555 11.0798 13.4556 10.3531 13.4556 9.49998C13.4556 8.64686 13.1555 7.92012 12.5551 7.31977C11.9548 6.71942 11.228 6.41925 10.3749 6.41925C9.52179 6.41925 8.79506 6.71942 8.19471 7.31977C7.59436 7.92012 7.29419 8.64686 7.29419 9.49998C7.29419 10.3531 7.59436 11.0798 8.19471 11.6802C8.79506 12.2805 9.52179 12.5807 10.3749 12.5807Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<span className="flex-1 ms-3 whitespace-nowrap">Settings</span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
to="#"
|
||||||
|
className="flex items-center p-2 pt-4 pb-4 text-white rounded-lg dark:text-white hover:bg-[#37A0EA] dark:hover:bg-[#37A0EA] group"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="w-5 h-5 text-white dark:text-white self-center"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M8.586 2.586A2 2 0 0 1 10 2h4a2 2 0 0 1 2 2v2h3a1 1 0 1 1 0 2v12a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V8a1 1 0 0 1 0-2h3V4a2 2 0 0 1 .586-1.414ZM10 6h4V4h-4v2Zm1 4a1 1 0 1 0-2 0v8a1 1 0 1 0 2 0v-8Zm4 0a1 1 0 1 0-2 0v8a1 1 0 1 0 2 0v-8Z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<span className="flex-1 ms-3 whitespace-nowrap">Trash</span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div className="mt-6 p-4 rounded-lg text-white">
|
||||||
|
{/* Cloud Icon + Title */}
|
||||||
|
<div className="flex items-center">
|
||||||
|
<svg
|
||||||
|
className="w-7 h-7 text-white dark:text-white"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M13.383 4.076a6.5 6.5 0 0 0-6.887 3.95A5 5 0 0 0 7 18h3v-4a2 2 0 0 1-1.414-3.414l2-2a2 2 0 0 1 2.828 0l2 2A2 2 0 0 1 14 14v4h4a4 4 0 0 0 .988-7.876 6.5 6.5 0 0 0-5.605-6.048Z" />
|
||||||
|
<path d="M12.707 9.293a1 1 0 0 0-1.414 0l-2 2a1 1 0 1 0 1.414 1.414l.293-.293V19a1 1 0 1 0 2 0v-6.586l.293.293a1 1 0 0 0 1.414-1.414l-2-2Z" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<span className="ml-2 font-semibold">My Storage</span>
|
||||||
|
</div>
|
||||||
|
{/* Usage Text & Progress Bar */}
|
||||||
|
<p className="mt-2 text-lg">Used: of 100GB</p>
|
||||||
|
<div className="w-full bg-white rounded-full h-2 mt-2">
|
||||||
|
<div
|
||||||
|
className="bg-blue-500 h-2 rounded-full"
|
||||||
|
style={{ width: "24%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Sidebar;
|
||||||
+27
-1
@@ -1,2 +1,28 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@import "flowbite/src/themes/default";
|
|
||||||
|
/* For WebKit-based browsers */
|
||||||
|
.custom-scrollbar::-webkit-scrollbar {
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-scrollbar::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
/* or a color of your choice */
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-scrollbar::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #a0aec0;
|
||||||
|
/* Customize thumb color */
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
/* Optional: creates padding around thumb */
|
||||||
|
background-clip: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For Firefox */
|
||||||
|
.custom-scrollbar {
|
||||||
|
scrollbar-width: auto;
|
||||||
|
/* "auto" or "thin" */
|
||||||
|
scrollbar-color: #37A0EA transparent;
|
||||||
|
/* thumb and track colors */
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { FcGoogle } from "react-icons/fc";
|
|
||||||
import { FiEye, FiEyeOff } from "react-icons/fi";
|
import { FiEye, FiEyeOff } from "react-icons/fi";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
@@ -16,19 +15,7 @@ const Login = () => {
|
|||||||
<h1 className="text-2xl font-bold mb-6 text-gray-900 text-center">
|
<h1 className="text-2xl font-bold mb-6 text-gray-900 text-center">
|
||||||
Log in
|
Log in
|
||||||
</h1>
|
</h1>
|
||||||
<button className="flex items-center justify-center w-full py-3 mb-4 border border-gray-300 rounded-lg hover:bg-gray-50">
|
|
||||||
<FcGoogle className="text-xl mr-2" />
|
|
||||||
<span className="text-gray-700 font-medium">
|
|
||||||
Continue with Google
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<div className="flex items-center my-4">
|
|
||||||
<div className="flex-grow border-t border-gray-300" />
|
|
||||||
<span className="px-2 text-gray-500 text-sm">
|
|
||||||
Or login with email
|
|
||||||
</span>
|
|
||||||
<div className="flex-grow border-t border-gray-300" />
|
|
||||||
</div>
|
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<input
|
<input
|
||||||
@@ -38,14 +25,6 @@ const Login = () => {
|
|||||||
className="w-full border border-gray-300 rounded-l-lg px-4 py-4 focus:outline-none focus:border-blue-500"
|
className="w-full border border-gray-300 rounded-l-lg px-4 py-4 focus:outline-none focus:border-blue-500"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-6">
|
|
||||||
<Link
|
|
||||||
to="#!"
|
|
||||||
className="text-sm text-blue-600 hover:underline inline-block text-center"
|
|
||||||
>
|
|
||||||
Login via OTP
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-1">
|
<div className="mb-1">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
@@ -58,7 +37,7 @@ const Login = () => {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={togglePassword}
|
onClick={togglePassword}
|
||||||
className="absolute right-2 top-2 text-gray-500 hover:text-gray-700"
|
className="absolute right-2 top-4 text-2xl text-gray-500 hover:text-gray-700"
|
||||||
>
|
>
|
||||||
{showPassword ? <FiEyeOff /> : <FiEye />}
|
{showPassword ? <FiEyeOff /> : <FiEye />}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { FcGoogle } from "react-icons/fc";
|
|
||||||
import { FiEye, FiEyeOff } from "react-icons/fi";
|
import { FiEye, FiEyeOff } from "react-icons/fi";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ const SignUp = () => {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowPassword(!showPassword)}
|
onClick={() => setShowPassword(!showPassword)}
|
||||||
className="absolute right-3 top-3 text-gray-500 hover:text-gray-700"
|
className="absolute right-3 top-4 text-2xl text-gray-500 hover:text-gray-700"
|
||||||
>
|
>
|
||||||
{showPassword ? <FiEyeOff /> : <FiEye />}
|
{showPassword ? <FiEyeOff /> : <FiEye />}
|
||||||
</button>
|
</button>
|
||||||
@@ -56,7 +56,7 @@ const SignUp = () => {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
|
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
|
||||||
className="absolute right-3 top-3 text-gray-500 hover:text-gray-700"
|
className="absolute right-3 top-4 text-2xl text-gray-500 hover:text-gray-700"
|
||||||
>
|
>
|
||||||
{showConfirmPassword ? <FiEyeOff /> : <FiEye />}
|
{showConfirmPassword ? <FiEyeOff /> : <FiEye />}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
import React from "react";
|
||||||
|
import Sidebar from "../../components/Sidebar";
|
||||||
|
import FileList from "../../components/FileList";
|
||||||
|
import FileUpload from "../../components/FileUpload";
|
||||||
|
import { FiPlus } from "react-icons/fi";
|
||||||
|
|
||||||
|
const Dashboard = () => {
|
||||||
|
const [files, setFiles] = React.useState([]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
const response = await fetch(
|
||||||
|
"http://192.168.29.61:8080/api/hdfs/listFiles?hdfsPath=/"
|
||||||
|
);
|
||||||
|
const data = await response.json();
|
||||||
|
setFiles(data);
|
||||||
|
};
|
||||||
|
fetchData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* <!-- Main modal --> */}
|
||||||
|
<div
|
||||||
|
id="static-modal"
|
||||||
|
data-modal-backdrop="static"
|
||||||
|
tabindex="-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full"
|
||||||
|
>
|
||||||
|
<div class="relative p-4 w-full max-w-170 h-150 flex items-center justify-center">
|
||||||
|
{/* <!-- Modal content --> */}
|
||||||
|
<div class="relative bg-white rounded-lg shadow-sm ">
|
||||||
|
{/* <!-- Modal header --> */}
|
||||||
|
<div class="flex items-center justify-between p-2 md:p-5 rounded-t dark:border-gray-600 border-gray-200">
|
||||||
|
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">
|
||||||
|
Static modal
|
||||||
|
</h3>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
|
||||||
|
data-modal-hide="static-modal"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="w-3 h-3"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 14 14"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only">Close modal</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/* <!-- Modal body --> */}
|
||||||
|
<div class="p-4 md:p-5 space-y-4">
|
||||||
|
<FileUpload />
|
||||||
|
</div>
|
||||||
|
{/* <!-- Modal footer --> */}
|
||||||
|
{/* <div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b ">
|
||||||
|
<button
|
||||||
|
data-modal-hide="static-modal"
|
||||||
|
type="button"
|
||||||
|
class="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"
|
||||||
|
>
|
||||||
|
I accept
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
data-modal-hide="static-modal"
|
||||||
|
type="button"
|
||||||
|
class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
|
||||||
|
>
|
||||||
|
Decline
|
||||||
|
</button>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Sidebar />
|
||||||
|
<div className="p-4 sm:ml-64">
|
||||||
|
<div className="p-4 border-2 border-gray-200 border-dashed rounded-lg mt-14">
|
||||||
|
<div className="w-full flex justify-between items-center">
|
||||||
|
<h1 className="text-2xl font-bold mb-4">Dashboard</h1>
|
||||||
|
<button
|
||||||
|
data-modal-target="static-modal"
|
||||||
|
data-modal-toggle="static-modal"
|
||||||
|
class="block 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-3 py-2 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<FiPlus className="text-2xl" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FileList files={files}></FileList>
|
||||||
|
<section className="w-full flex justify-end items-center min-h-160">
|
||||||
|
{/* <!-- Modal toggle --> */}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Dashboard;
|
||||||
@@ -0,0 +1,376 @@
|
|||||||
|
import Footer from "../../components/Footer";
|
||||||
|
import React from "react";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
const DrivethruLandingPage = () => {
|
||||||
|
const features = [
|
||||||
|
{
|
||||||
|
title: "Easy Upload & Access",
|
||||||
|
description: "Drag & drop, instant access.",
|
||||||
|
icon: (
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M9 19l3 3m0 0l3-3m-3 3V10"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Secure & Private",
|
||||||
|
description: "End-to-end encryption.",
|
||||||
|
icon: (
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Seamless Sharing",
|
||||||
|
description: "Share files with one click.",
|
||||||
|
icon: (
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Access Anywhere",
|
||||||
|
description: "Works on all devices.",
|
||||||
|
icon: (
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h.5A2.5 2.5 0 0020 5.5v-1.65"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const howItWorks = [
|
||||||
|
{
|
||||||
|
title: "Create an account",
|
||||||
|
description: "Sign up in seconds.",
|
||||||
|
icon: (
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Upload files",
|
||||||
|
description: "Drag & drop or select from your device.",
|
||||||
|
icon: (
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Manage files",
|
||||||
|
description: "Rename, move, or delete easily.",
|
||||||
|
icon: (
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Access anytime",
|
||||||
|
description: "Open files from any device.",
|
||||||
|
icon: (
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// UseEffect and handle....click function to handle set and handle the animation of features..
|
||||||
|
const [activeIndex, setActiveIndex] = useState(0);
|
||||||
|
const [isPaused, setIsPaused] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isPaused) {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
setActiveIndex((prevIndex) => (prevIndex + 1) % features.length);
|
||||||
|
}, 3000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}
|
||||||
|
}, [isPaused, features.length]);
|
||||||
|
|
||||||
|
// Handle user interaction
|
||||||
|
const handleFeatureClick = (index) => {
|
||||||
|
setActiveIndex(index);
|
||||||
|
setIsPaused(true);
|
||||||
|
setTimeout(() => setIsPaused(false), 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const [activeIndex1, setActiveIndex1] = useState(0);
|
||||||
|
const [isPaused1, setIsPaused1] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isPaused1) {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
setActiveIndex1((prevIndex) => (prevIndex + 1) % howItWorks.length);
|
||||||
|
}, 3000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}
|
||||||
|
}, [isPaused1, howItWorks.length]);
|
||||||
|
|
||||||
|
const handleFeatureClick1 = (index) => {
|
||||||
|
setActiveIndex1(index);
|
||||||
|
setIsPaused1(true);
|
||||||
|
setTimeout(() => setIsPaused1(false), 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen overflow-x-hidden bg-white">
|
||||||
|
{/* Hero Section */}
|
||||||
|
<div
|
||||||
|
id="about"
|
||||||
|
className="bg-gradient-to-r from-blue-50 to-white min-h-[90vh] flex items-center relative"
|
||||||
|
>
|
||||||
|
<div className="container mx-auto px-4 md:px-6 lg:px-8 relative z-10">
|
||||||
|
<div className="flex flex-col md:flex-row items-center gap-8 lg:gap-12">
|
||||||
|
{/* Left Side - Text Content */}
|
||||||
|
<div className="w-full md:w-1/2 text-center md:text-left order-1 md:order-1">
|
||||||
|
<div className="flex justify-center md:justify-start items-center mb-6 lg:mb-8">
|
||||||
|
<div className="text-cyan-400 mr-2 md:mr-3">
|
||||||
|
<svg
|
||||||
|
className="w-10 md:w-12 h-10 md:h-12"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M12 2L2 12L12 22L22 12L12 2Z"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="3"
|
||||||
|
fill="none"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h1 className="text-4xl md:text-5xl font-bold text-black">
|
||||||
|
Drive-thru
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 className="text-xl md:text-2xl font-bold mb-4 md:mb-6 text-black">
|
||||||
|
Store, Access & Share Your Files — Anytime, Anywhere!
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p className="text-gray-800 mb-6 md:mb-10 text-base md:text-lg">
|
||||||
|
A simple, secure, and fast cloud storage solution for all your
|
||||||
|
files. Upload, organize, and access with ease.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* Buttons */}
|
||||||
|
<div className="flex flex-col sm:flex-row justify-center md:justify-start space-y-4 sm:space-y-0 sm:space-x-4">
|
||||||
|
<Link
|
||||||
|
to="/signup"
|
||||||
|
className="bg-emerald-500 hover:bg-emerald-600 text-white font-medium rounded-full px-6 py-4 md:px-8 md:py-6 transform hover:scale-105 transition-all duration-300 shadow-lg hover:shadow-xl"
|
||||||
|
>
|
||||||
|
Get Started
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
to="/login"
|
||||||
|
className="bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-full px-6 py-4 md:px-8 md:py-6 transform hover:scale-105 transition-all duration-300 shadow-lg hover:shadow-xl"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Right Side - Image */}
|
||||||
|
<div className="w-full md:w-1/2 flex justify-center order-2 md:order-1">
|
||||||
|
<div className="relative p-4 bg-gradient-to-r from-blue-50 to-emerald-50 rounded-2xl max-w-xs sm:max-w-lg md:max-w-md lg:max-w-lvh">
|
||||||
|
<img
|
||||||
|
src="/Dashboard.png"
|
||||||
|
alt="Drive-thru Dashboard Interface"
|
||||||
|
className="w-full rounded-xl shadow-2xl transition-shadow duration-300"
|
||||||
|
/>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-r from-blue-500/5 to-emerald-500/5 rounded-2xl pointer-events-none"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Features Section */}
|
||||||
|
<div
|
||||||
|
id="features"
|
||||||
|
className="w-full max-w-5xl mx-auto p-6 sm:p-8 bg-gray-100 rounded-lg shadow-lg"
|
||||||
|
>
|
||||||
|
<h2 className="text-3xl font-bold text-center mb-8">Key Features</h2>
|
||||||
|
<div className="flex flex-col-reverse md:flex-row items-center gap-8 lg:gap-12">
|
||||||
|
{/* Left Side - Image */}
|
||||||
|
<div className="w-full md:w-1/2 flex justify-center">
|
||||||
|
<img
|
||||||
|
src="/He.png"
|
||||||
|
alt="Feature Illustration"
|
||||||
|
className="w-full max-w-xs sm:max-w-sm md:max-w-md lg:max-w-lg object-contain rounded-lg shadow-md"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right Side - Feature List */}
|
||||||
|
<div className="w-full md:w-1/2">
|
||||||
|
<div className="space-y-6">
|
||||||
|
{features.map((feature, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`p-5 border-2 rounded-lg cursor-pointer transition-all duration-500 ${
|
||||||
|
index === activeIndex
|
||||||
|
? "border-blue-500 bg-white shadow-lg scale-105"
|
||||||
|
: "border-gray-300"
|
||||||
|
}`}
|
||||||
|
onClick={() => handleFeatureClick(index)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center space-x-4">
|
||||||
|
{feature.icon}
|
||||||
|
<h3 className="text-lg font-semibold">{feature.title}</h3>
|
||||||
|
</div>
|
||||||
|
{index === activeIndex && (
|
||||||
|
<p className="text-gray-600 mt-3 transition-opacity duration-500 opacity-100">
|
||||||
|
{feature.description}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* How It Works Section */}
|
||||||
|
<div
|
||||||
|
id="howItWorks"
|
||||||
|
className="w-full max-w-5xl mx-auto p-6 sm:p-8 bg-gray-100 rounded-lg shadow-lg"
|
||||||
|
>
|
||||||
|
<h2 className="text-3xl font-bold text-center mb-8">How It Works</h2>
|
||||||
|
<div className="flex flex-col md:flex-row items-center gap-8 lg:gap-12">
|
||||||
|
{/* Left Side - Feature List */}
|
||||||
|
<div className="w-full md:w-1/2">
|
||||||
|
<div className="space-y-6">
|
||||||
|
{howItWorks.map((howItWork, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`p-5 border-2 rounded-lg cursor-pointer transition-all duration-500 ${
|
||||||
|
index === activeIndex1
|
||||||
|
? "border-blue-500 bg-white shadow-lg scale-105"
|
||||||
|
: "border-gray-300"
|
||||||
|
}`}
|
||||||
|
onClick={() => handleFeatureClick1(index)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center space-x-4">
|
||||||
|
{howItWork.icon}
|
||||||
|
<h3 className="text-lg font-semibold">{howItWork.title}</h3>
|
||||||
|
</div>
|
||||||
|
{index === activeIndex1 && (
|
||||||
|
<p className="text-gray-600 mt-3 transition-opacity duration-500 opacity-100">
|
||||||
|
{howItWork.description}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right Side - Image */}
|
||||||
|
<div className="w-full md:w-1/2 flex justify-center">
|
||||||
|
<img
|
||||||
|
src="/She.png"
|
||||||
|
alt="Feature Illustration"
|
||||||
|
className="w-full max-w-xs sm:max-w-sm md:max-w-md lg:max-w-lg object-contain rounded-lg shadow-md"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DrivethruLandingPage;
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
const NotFoundPage = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center justify-center h-screen bg-gray-100 p-4">
|
||||||
|
{/* Placeholder SVG - Replace this with your SVG */}
|
||||||
|
<img
|
||||||
|
src="/404.png"
|
||||||
|
style={{ width: "30%", height: "auto" }}
|
||||||
|
alt="404 Not Found"
|
||||||
|
></img>
|
||||||
|
{/* Page number and title */}
|
||||||
|
<h2 className="text-2xl font-bold mb-4 mt-4">Page Not Found</h2>
|
||||||
|
|
||||||
|
{/* Description text */}
|
||||||
|
<p className="text-center text-gray-700 mb-6">
|
||||||
|
Sorry, we couldn't find the page you were looking for. It may have
|
||||||
|
been moved or deleted.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* Call-to-action button */}
|
||||||
|
<Link
|
||||||
|
to="/"
|
||||||
|
className="px-6 py-2 bg-[#1877F2] text-white rounded hover:bg-blue-600 transition duration-200"
|
||||||
|
>
|
||||||
|
Go Home
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NotFoundPage;
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// utils/api.js
|
||||||
|
export const uploadFileToHDFS = async (
|
||||||
|
file,
|
||||||
|
hdfsPath,
|
||||||
|
uploadedFileName,
|
||||||
|
username
|
||||||
|
) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", file);
|
||||||
|
formData.append("hdfsPath", "/kalas");
|
||||||
|
formData.append("uploadedFileName", uploadedFileName);
|
||||||
|
formData.append("username", "kalas");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
"http://192.168.29.61:8080/api/hdfs/uploadFile",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json(); // or response.json() if JSON is returned
|
||||||
|
|
||||||
|
console.log("Response:", data);
|
||||||
|
} else {
|
||||||
|
console.error("Upload failed with status:", response.status);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error uploading file:", error);
|
||||||
|
alert("An error occurred while uploading the file.");
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -4,6 +4,13 @@ import tailwindcss from '@tailwindcss/vite'
|
|||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react(), tailwindcss(),
|
plugins: [
|
||||||
|
react(),
|
||||||
|
tailwindcss(),
|
||||||
],
|
],
|
||||||
|
server: {
|
||||||
|
host: 'localhost',
|
||||||
|
port: 5173,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "cc-mini",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user