This repository has been archived on 2026-03-26. You can view files and clone it, but cannot push or open issues or pull requests.

146 lines
4.8 KiB
JavaScript

import {useEffect, useState} from "react";
import {useNavigate} from "react-router-dom";
import DirectoryList from "../components/DirectoryList.jsx";
import PathDisplay from "../components/ PathDisplay.jsx";
import Navbar from "../components/Navbar.jsx";
export default function Dashboard() {
const [username, setUsername] = useState("");
const [path, setPath] = useState(["home", "azpect"]);
const [showHidden, setShowHidden] = useState(false);
const [selected, setSelected] = useState([]);
const [files, setFiles] = useState([]);
const navigate = useNavigate();
useEffect(() => {
const getData = async () => {
console.log(`http://localhost:5000/v1/children?path=/${path.join("/")}`);
const response = await fetch(`http://localhost:5000/v1/children?path=/${path.join("/")}`)
if (!response.ok) {
console.error("Something went wrong");
}
return await response.json();
}
getData().then((data) => {
setFiles(data);
});
setSelected([]);
}, [path]);
/**
* The name of the value stored in local storage.
* @type {string}
*/
const storage_id = "gophernest_credentials";
// Redirect if the user isn't logged in, otherwise update the state.
useEffect(() => {
if (localStorage.getItem(storage_id) == null && sessionStorage.getItem(storage_id) == null) {
navigate("/login");
} else {
if (localStorage.getItem(storage_id)) {
setUsername(JSON.parse(localStorage.getItem(storage_id))["username"]);
} else if (sessionStorage.getItem(storage_id)) {
setUsername(JSON.parse(sessionStorage.getItem(storage_id))["username"]);
}
}
}, [navigate]);
/**
* Updates the path by slicing [0:index]
* @param index {number} Index to slice to.
*/
const updatePath = (index) => {
setPath(path.slice(0, index + 1));
};
/**
* Set the path back to the default, home directory.
*/
const backHome = () => {
setPath(["home", "azpect"]);
};
/**
* Add name to the path.
* @param name Targe child
*/
const appendPath = (name) => {
setPath([...path, name])
};
/**
* Back arrow, goes back one directory (cd ..)
*/
const backArrow = () => {
setPath(path.slice(0, path.length - 1));
}
/**
* This isn't fast, but hopefully the use case will be small batches.
* @param file {string} The file to toggle
*/
const toggleSelected = (file) => {
if (!selected.includes(file)) {
setSelected([...selected, file]);
} else {
const idx = selected.indexOf(file);
setSelected([...selected.slice(0, idx), ...selected.slice(idx + 1, selected.length)])
}
};
/**
* Callback function for when the download button is clicked.
*/
const downloadFiles = () => {
const download = async (paths) => {
try {
const resp = await fetch("http://localhost:5000/v1/download", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({filePaths: paths}),
});
if (!resp.ok) {
throw new Error(`HTTP error! status: ${resp.status}`);
}
const blob = await resp.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = "downloads.zip";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
} catch (err) {
console.error(`Download error: ${err}`);
}
};
const targets = [];
selected.forEach((file) => {
targets.push(`/${path.join("/")}/${file}`);
});
console.log(targets);
download(targets);
};
return (
<div className="w-full min-h-screen h-screen pb-8">
<Navbar downloadFiles={downloadFiles}/>
<div className="h-full w-full flex flex-col items-center justify-center pb-8">
<PathDisplay path={path} updatePath={updatePath} backHome={backHome} backArrow={backArrow}/>
<div className="w-2/3 h-5/6 overflow-y-auto border-1 border-gray-300">
<DirectoryList dirs={files} showHidden={showHidden} appendPath={appendPath}
toggleSelected={toggleSelected}/>
</div>
</div>
</div>
)
}