add 404.html and new upload page
This commit is contained in:
+6
-2
@@ -1,5 +1,5 @@
|
|||||||
# app/frontend.py (new file or inline in main.py)
|
# app/frontend.py (new file or inline in main.py)
|
||||||
from fastapi import APIRouter, Request
|
from fastapi import APIRouter, Request, status
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from app.auth import require_login
|
from app.auth import require_login
|
||||||
@@ -24,4 +24,8 @@ async def serve_upload(request: Request):
|
|||||||
# 3) Serve favicon.ico from the frontend folder
|
# 3) Serve favicon.ico from the frontend folder
|
||||||
@router.get("/favicon.ico", response_class=FileResponse)
|
@router.get("/favicon.ico", response_class=FileResponse)
|
||||||
def favicon():
|
def favicon():
|
||||||
return os.path.join(frontend_folder, "favicon.ico")
|
return os.path.join(frontend_folder, "favicon.ico")
|
||||||
|
|
||||||
|
@app.exception_handler(404)
|
||||||
|
async def custom_404_handler(request: Request, exc):
|
||||||
|
return FileResponse("frontend/404.html", status_code=status.HTTP_404_NOT_FOUND)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>404 - Page not found</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
||||||
|
</head>
|
||||||
|
<body class="bg-gray-50 h-screen flex flex-col items-center justify-center">
|
||||||
|
<h1 class="text-4xl font-bold mb-4">404 - Page not found</h1>
|
||||||
|
<p class="text-gray-700 mb-8">
|
||||||
|
Sorry, we couldn’t find the page you’re looking for.
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href="/"
|
||||||
|
class="text-blue-600 underline text-lg hover:text-blue-800"
|
||||||
|
>
|
||||||
|
← Back to home
|
||||||
|
</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+80
-27
@@ -1,45 +1,78 @@
|
|||||||
<!-- File: frontend/index.html -->
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Document Processor - Upload</title>
|
<title>Document Processor - Upload</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<!-- Tailwind via CDN or your own build -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
||||||
<script>
|
|
||||||
// Optional: Additional JS for drag-and-drop, or you can keep it inline.
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-gray-50 h-screen flex flex-col items-center justify-center">
|
<body class="bg-gray-50 h-screen flex flex-col">
|
||||||
<h1 class="text-3xl font-bold mb-8">Upload a File</h1>
|
|
||||||
|
|
||||||
<div
|
<!-- Navigation Bar -->
|
||||||
id="dropZone"
|
<nav class="bg-white shadow">
|
||||||
class="border-4 border-dashed border-gray-300 rounded-lg p-8 bg-white text-center w-1/2"
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex justify-between h-16 items-center">
|
||||||
ondrop="handleDrop(event)"
|
<!-- Brand -->
|
||||||
ondragover="handleDragOver(event)"
|
<div class="flex-shrink-0">
|
||||||
>
|
<a href="/" class="text-xl font-bold text-blue-500 hover:text-blue-700">
|
||||||
<p class="text-gray-500">
|
Document Processor
|
||||||
Drag & drop a file here, or click to select a file.
|
</a>
|
||||||
</p>
|
</div>
|
||||||
<input
|
<!-- Menu items on the right -->
|
||||||
id="fileInput"
|
<div class="flex space-x-4 items-center">
|
||||||
type="file"
|
<!-- Example link to /upload (current page), or other pages -->
|
||||||
class="hidden"
|
<a href="/upload" class="text-gray-700 hover:text-gray-900">
|
||||||
onchange="handleFileSelect(event)"
|
Upload
|
||||||
/>
|
</a>
|
||||||
</div>
|
<!-- Placeholder for future pages -->
|
||||||
|
<a href="/some-other" class="text-gray-700 hover:text-gray-900">
|
||||||
|
Some Page
|
||||||
|
</a>
|
||||||
|
<!-- Dynamic login/logout section -->
|
||||||
|
<div id="authSection" class="text-gray-700 hover:text-gray-900"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
<div id="statusMessage" class="mt-4 text-gray-700"></div>
|
<!-- Main content area -->
|
||||||
|
<main class="flex-grow flex flex-col items-center justify-center p-8">
|
||||||
|
<h1 class="text-3xl font-bold mb-8">Upload a File</h1>
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="dropZone"
|
||||||
|
class="border-4 border-dashed border-gray-300 rounded-lg p-8 bg-white text-center w-full max-w-lg"
|
||||||
|
ondrop="handleDrop(event)"
|
||||||
|
ondragover="handleDragOver(event)"
|
||||||
|
>
|
||||||
|
<p class="text-gray-500 mb-4">
|
||||||
|
Drag & drop a file here, or click to select a file.
|
||||||
|
</p>
|
||||||
|
<input
|
||||||
|
id="fileInput"
|
||||||
|
type="file"
|
||||||
|
class="hidden"
|
||||||
|
onchange="handleFileSelect(event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="statusMessage" class="mt-4 text-gray-700"></div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- Footer (optional) -->
|
||||||
|
<footer class="bg-white shadow mt-auto">
|
||||||
|
<div class="max-w-7xl mx-auto px-4 py-4 text-center text-gray-600">
|
||||||
|
© 2025 Document Processor - All rights reserved.
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- JavaScript -->
|
||||||
<script>
|
<script>
|
||||||
|
// 1) Drag-and-drop / file input logic
|
||||||
const dropZone = document.getElementById("dropZone");
|
const dropZone = document.getElementById("dropZone");
|
||||||
const fileInput = document.getElementById("fileInput");
|
const fileInput = document.getElementById("fileInput");
|
||||||
const statusMessage = document.getElementById("statusMessage");
|
const statusMessage = document.getElementById("statusMessage");
|
||||||
|
|
||||||
dropZone.addEventListener("click", () => {
|
dropZone.addEventListener("click", () => fileInput.click());
|
||||||
fileInput.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleDragOver(e) {
|
function handleDragOver(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -65,7 +98,6 @@
|
|||||||
statusMessage.textContent = `Uploading ${file.name}...`;
|
statusMessage.textContent = `Uploading ${file.name}...`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// We'll POST the file to /upload
|
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
|
|
||||||
@@ -84,6 +116,27 @@
|
|||||||
statusMessage.textContent = `Error: ${err}`;
|
statusMessage.textContent = `Error: ${err}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2) Example dynamic auth check: if you have an endpoint like /api/whoami
|
||||||
|
// that returns JSON with { email: "..."} if logged in, or 401 if not.
|
||||||
|
(async function checkAuth() {
|
||||||
|
try {
|
||||||
|
const resp = await fetch("/api/whoami");
|
||||||
|
if (resp.ok) {
|
||||||
|
const data = await resp.json();
|
||||||
|
document.getElementById("authSection").innerHTML =
|
||||||
|
`Logged in as <strong>${data.email}</strong> <a href="/logout" class="ml-2 text-blue-600">Logout</a>`;
|
||||||
|
} else {
|
||||||
|
// If 401 or other non-OK status => show Login link
|
||||||
|
document.getElementById("authSection").innerHTML =
|
||||||
|
`<a href="/login" class="text-blue-600">Login</a>`;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// If fetch fails, also show login
|
||||||
|
document.getElementById("authSection").innerHTML =
|
||||||
|
`<a href="/login" class="text-blue-600">Login</a>`;
|
||||||
|
}
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user