basic poc
This commit is contained in:
parent
a374549fa1
commit
8591ec376b
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Virtual Environment Directories
|
||||||
|
venv/
|
||||||
|
__pycache__/
|
25
backend/README.md
Normal file
25
backend/README.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Dashboard UI
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
This is a proof-of-concept of a basic Dashboard UI in Python using FastApi and HTMX.
|
||||||
|
|
||||||
|
## Deploy Locally
|
||||||
|
|
||||||
|
```
|
||||||
|
# Clone the repository
|
||||||
|
git clone https://git.ourworld.tf/tfgrid/ui_poc
|
||||||
|
# Go to backend
|
||||||
|
cd ui_poc/backend
|
||||||
|
# Set Python environment
|
||||||
|
python3 -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
# Install requirements
|
||||||
|
python3 -m pip install -r requirements.txt
|
||||||
|
# Deploy the local website at port 8000
|
||||||
|
uvicorn main:app --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
The .gitignore file is set with `venv` as the Python virtual environment.
|
BIN
backend/frontend/favicon.png
Normal file
BIN
backend/frontend/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 426 B |
34
backend/frontend/index.html
Normal file
34
backend/frontend/index.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<!-- frontend/index.html -->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>User Dashboard</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
||||||
|
<script src="//unpkg.com/alpinejs" defer></script>
|
||||||
|
<script src="//unpkg.com/htmx.org@1.8.4" defer></script>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
</head>
|
||||||
|
<body x-data="{ activePage: 'home' }" @htmx:afterSwap="activePage = event.detail.target.id" class="flex">
|
||||||
|
<div class="w-1/4 h-screen bg-gray-800 text-white">
|
||||||
|
<div class="p-5">
|
||||||
|
<h1 class="text-xl font-bold">Dashboard</h1>
|
||||||
|
</div>
|
||||||
|
<ul class="mt-5 space-y-2">
|
||||||
|
<li><a href="#" hx-get="/pages/home" hx-target="#main-content" hx-push-url="true" class="block p-3 hover:bg-gray-600">Home</a></li>
|
||||||
|
<li><a href="#" hx-get="/pages/profile" hx-target="#main-content" hx-push-url="true" class="block p-3 hover:bg-gray-600" @click="activePage = 'profile'">Profile</a></li>
|
||||||
|
<li><a href="#" hx-get="/pages/chat" hx-target="#main-content" hx-push-url="true" class="block p-3 hover:bg-gray-600" @click="activePage = 'chat'">Chat</a></li>
|
||||||
|
<li><a href="#" hx-get="/pages/video" hx-target="#main-content" hx-push-url="true" class="block p-3 hover:bg-gray-600" @click="activePage = 'video'">Video</a></li>
|
||||||
|
<li><a href="#" hx-get="/pages/calendar" hx-target="#main-content" hx-push-url="true" class="block p-3 hover:bg-gray-600" @click="activePage = 'calendar'">Calendar</a></li>
|
||||||
|
<li><a href="#" hx-get="/pages/file_management" hx-target="#main-content" hx-push-url="true" class="block p-3 hover:bg-gray-600" @click="activePage = 'file_management'">File Management</a></li>
|
||||||
|
<li><a href="#" hx-get="/pages/settings" hx-target="#main-content" hx-push-url="true" class="block p-3 hover:bg-gray-600" @click="activePage = 'settings'">Settings</a></li>
|
||||||
|
<li><a href="#" hx-get="/pages/logout" hx-target="#main-content" hx-push-url="true" class="block p-3 hover:bg-gray-600">Log Out</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="main-content" class="flex-1 p-10">
|
||||||
|
<h2 class="text-2xl font-semibold" id="home">Welcome to Your Dashboard</h2>
|
||||||
|
<p class="mt-5" id="welcome">Select an option from the menu on the left to get started.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
20
backend/frontend/pages/calendar.html
Normal file
20
backend/frontend/pages/calendar.html
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<!-- frontend/pages/calendar.html -->
|
||||||
|
<div id="calendar" class="content">
|
||||||
|
<h3 class="text-xl font-semibold">Calendar</h3>
|
||||||
|
<p class="mt-3">Keep track of your events and appointments.</p>
|
||||||
|
<div class="mt-5">
|
||||||
|
<p>You can add your events using the form below:</p>
|
||||||
|
<form class="mt-2">
|
||||||
|
<label class="block mb-2">Event Title:</label>
|
||||||
|
<input type="text" class="border rounded p-2 mb-4 w-full" placeholder="Meeting with John">
|
||||||
|
|
||||||
|
<label class="block mb-2">Date:</label>
|
||||||
|
<input type="date" class="border rounded p-2 mb-4 w-full">
|
||||||
|
|
||||||
|
<label class="block mb-2">Time:</label>
|
||||||
|
<input type="time" class="border rounded p-2 mb-4 w-full">
|
||||||
|
|
||||||
|
<button type="submit" class="bg-blue-500 text-white rounded p-2">Add Event</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
15
backend/frontend/pages/chat.html
Normal file
15
backend/frontend/pages/chat.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<!-- frontend/pages/chat.html -->
|
||||||
|
<div id="chat" class="content">
|
||||||
|
<h3 class="text-xl font-semibold">Chat</h3>
|
||||||
|
<p class="mt-3">Connect with your contacts in real-time.</p>
|
||||||
|
<div class="mt-5">
|
||||||
|
<div class="border rounded p-4 h-64 overflow-y-scroll">
|
||||||
|
<div class="mb-2"><strong>Contact 1:</strong> Hey, how are you?</div>
|
||||||
|
<div class="mb-2"><strong>You:</strong> I'm doing well, thanks! And you?</div>
|
||||||
|
<div class="mb-2"><strong>Contact 1:</strong> Good to hear!</div>
|
||||||
|
<div class="mb-2"><strong>Contact 2:</strong> Did you see the news?</div>
|
||||||
|
</div>
|
||||||
|
<input type="text" class="border rounded p-2 mt-2 w-full" placeholder="Type your message...">
|
||||||
|
<button class="bg-blue-500 text-white rounded p-2 mt-2">Send</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
22
backend/frontend/pages/file_management.html
Normal file
22
backend/frontend/pages/file_management.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<!-- frontend/pages/file_management.html -->
|
||||||
|
<div id="file_management" class="content">
|
||||||
|
<h3 class="text-xl font-semibold">File Management</h3>
|
||||||
|
<p class="mt-3">Upload and manage your files.</p>
|
||||||
|
<div class="mt-5">
|
||||||
|
<input type="file" class="mb-4">
|
||||||
|
<button class="bg-blue-500 text-white rounded p-2">Upload</button>
|
||||||
|
|
||||||
|
<h4 class="mt-5">Your Files:</h4>
|
||||||
|
<ul>
|
||||||
|
<li class="mb-2">
|
||||||
|
<a href="#" class="text-blue-600 hover:underline">Document 1.pdf</a>
|
||||||
|
</li>
|
||||||
|
<li class="mb-2">
|
||||||
|
<a href="#" class="text-blue-600 hover:underline">Image 2.jpg</a>
|
||||||
|
</li>
|
||||||
|
<li class="mb-2">
|
||||||
|
<a href="#" class="text-blue-600 hover:underline">Presentation.pptx</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
49
backend/frontend/pages/home.html
Normal file
49
backend/frontend/pages/home.html
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<!-- frontend/pagess/home.html -->
|
||||||
|
<div id="home" class="content">
|
||||||
|
<h3 class="text-xl font-semibold">Home</h3>
|
||||||
|
<p class="mt-3">Welcome to your dashboard! Click on a section below to view more details.</p>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mt-5">
|
||||||
|
<div class="bg-white rounded shadow p-5">
|
||||||
|
<h4 class="text-lg font-semibold">Profile</h4>
|
||||||
|
<p class="mt-2">Manage your personal information and settings.</p>
|
||||||
|
<a href="#" hx-get="/pages/profile" hx-target="#main-content" hx-push-url="true"
|
||||||
|
class="text-blue-600 hover:underline mt-3 block">Go to Profile</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded shadow p-5">
|
||||||
|
<h4 class="text-lg font-semibold">Chat</h4>
|
||||||
|
<p class="mt-2">Connect with your contacts in real-time.</p>
|
||||||
|
<a href="#" hx-get="/pages/chat" hx-target="#main-content" hx-push-url="true"
|
||||||
|
class="text-blue-600 hover:underline mt-3 block">Go to Chat</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded shadow p-5">
|
||||||
|
<h4 class="text-lg font-semibold">Videos</h4>
|
||||||
|
<p class="mt-2">Watch and manage your video content.</p>
|
||||||
|
<a href="#" hx-get="/pages/video" hx-target="#main-content" hx-push-url="true"
|
||||||
|
class="text-blue-600 hover:underline mt-3 block">Go to Videos</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded shadow p-5">
|
||||||
|
<h4 class="text-lg font-semibold">Calendar</h4>
|
||||||
|
<p class="mt-2">Keep track of your events and appointments.</p>
|
||||||
|
<a href="#" hx-get="/pages/calendar" hx-target="#main-content" hx-push-url="true"
|
||||||
|
class="text-blue-600 hover:underline mt-3 block">Go to Calendar</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded shadow p-5">
|
||||||
|
<h4 class="text-lg font-semibold">File Management</h4>
|
||||||
|
<p class="mt-2">Upload and manage your files.</p>
|
||||||
|
<a href="#" hx-get="/pages/file_management" hx-target="#main-content" hx-push-url="true"
|
||||||
|
class="text-blue-600 hover:underline mt-3 block">Go to File Management</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded shadow p-5">
|
||||||
|
<h4 class="text-lg font-semibold">Settings</h4>
|
||||||
|
<p class="mt-2">Customize your application settings.</p>
|
||||||
|
<a href="#" hx-get="/pages/settings" hx-target="#main-content" hx-push-url="true"
|
||||||
|
class="text-blue-600 hover:underline mt-3 block">Go to Settings</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
15
backend/frontend/pages/login.html
Normal file
15
backend/frontend/pages/login.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<!-- frontend/pages/login.html -->
|
||||||
|
<div id="login" class="content">
|
||||||
|
<h3 class="text-xl font-semibold">Login</h3>
|
||||||
|
<p class="mt-3">Please enter your credentials to log in.</p>
|
||||||
|
<form id="login-form" hx-post="/login" hx-target="#main-content" hx-swap="innerHTML" class="mt-5">
|
||||||
|
<label class="block mb-2">Email:</label>
|
||||||
|
<input type="email" name="email" class="border rounded p-2 mb-4 w-full" placeholder="Email" required>
|
||||||
|
|
||||||
|
<label class="block mb-2">Password:</label>
|
||||||
|
<input type="password" name="password" class="border rounded p-2 mb-4 w-full" placeholder="Password" required>
|
||||||
|
|
||||||
|
<button type="submit" class="bg-blue-500 text-white rounded p-2">Login</button>
|
||||||
|
</form>
|
||||||
|
<div id="login-error" class="text-red-600 mt-2"></div>
|
||||||
|
</div>
|
8
backend/frontend/pages/logout.html
Normal file
8
backend/frontend/pages/logout.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<!-- frontend/pages/logout.html -->
|
||||||
|
<div id="logout" class="content">
|
||||||
|
<h3 class="text-xl font-semibold">Logout</h3>
|
||||||
|
<p class="mt-3">You have been logged out successfully.</p>
|
||||||
|
<p>
|
||||||
|
<a href="/" class="text-blue-600 hover:underline">Return to Dashboard</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
16
backend/frontend/pages/profile.html
Normal file
16
backend/frontend/pages/profile.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!-- frontend/pages/profile.html -->
|
||||||
|
<div id="profile" class="content">
|
||||||
|
<h3 class="text-xl font-semibold">Profile</h3>
|
||||||
|
<p class="mt-3">Manage your profile settings and personal information.</p>
|
||||||
|
<div class="mt-5">
|
||||||
|
<form>
|
||||||
|
<label class="block mb-2">Name:</label>
|
||||||
|
<input type="text" class="border rounded p-2 mb-4 w-full" placeholder="John Doe">
|
||||||
|
|
||||||
|
<label class="block mb-2">Email:</label>
|
||||||
|
<input type="email" class="border rounded p-2 mb-4 w-full" placeholder="john.doe@example.com">
|
||||||
|
|
||||||
|
<button type="submit" class="bg-blue-500 text-white rounded p-2">Update Profile</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
20
backend/frontend/pages/settings.html
Normal file
20
backend/frontend/pages/settings.html
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<!-- frontend/pages/settings.html -->
|
||||||
|
<div id="settings" class="content">
|
||||||
|
<h3 class="text-xl font-semibold">Settings</h3>
|
||||||
|
<p class="mt-3">Customize your application settings.</p>
|
||||||
|
<div class="mt-5">
|
||||||
|
<form>
|
||||||
|
<label class="block mb-2">Notification Preferences:</label>
|
||||||
|
<select class="border rounded p-2 mb-4 w-full">
|
||||||
|
<option>Email</option>
|
||||||
|
<option>SMS</option>
|
||||||
|
<option>Push Notifications</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label class="block mb-2">Change Password:</label>
|
||||||
|
<input type="password" class="border rounded p-2 mb-4 w-full" placeholder="New Password">
|
||||||
|
|
||||||
|
<button type="submit" class="bg-blue-500 text-white rounded p-2">Save Settings</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
18
backend/frontend/pages/video.html
Normal file
18
backend/frontend/pages/video.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!-- frontend/pages/video.html -->
|
||||||
|
<div id="video" class="content">
|
||||||
|
<h3 class="text-xl font-semibold">Videos</h3>
|
||||||
|
<p class="mt-3">Watch and manage your video content.</p>
|
||||||
|
<div class="mt-5">
|
||||||
|
<ul>
|
||||||
|
<li class="mb-2">
|
||||||
|
<a href="#" class="text-blue-600 hover:underline">Video 1: Introduction to HTML</a>
|
||||||
|
</li>
|
||||||
|
<li class="mb-2">
|
||||||
|
<a href="#" class="text-blue-600 hover:underline">Video 2: Understanding CSS</a>
|
||||||
|
</li>
|
||||||
|
<li class="mb-2">
|
||||||
|
<a href="#" class="text-blue-600 hover:underline">Video 3: JavaScript Basics</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
13
backend/frontend/style.css
Normal file
13
backend/frontend/style.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* frontend/style.css */
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Arial', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content h3 {
|
||||||
|
margin-top: 25;
|
||||||
|
}
|
24
backend/main.py
Normal file
24
backend/main.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# backend/main.py
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.responses import HTMLResponse
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
# Serve static files
|
||||||
|
app.mount("/static", StaticFiles(directory="frontend"), name="static")
|
||||||
|
|
||||||
|
# Home route
|
||||||
|
@app.get("/", response_class=HTMLResponse)
|
||||||
|
async def read_root():
|
||||||
|
with open("frontend/index.html", "r") as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
# Dynamic routes for different dashboard pages; all pages served from the `pages` directory
|
||||||
|
@app.get("/pages/{page_name}", response_class=HTMLResponse)
|
||||||
|
async def get_page(page_name: str):
|
||||||
|
try:
|
||||||
|
with open(f"frontend/pages/{page_name}.html", "r") as f:
|
||||||
|
return f.read()
|
||||||
|
except FileNotFoundError:
|
||||||
|
return HTMLResponse(content="Page not found", status_code=404)
|
4
backend/requirements.txt
Normal file
4
backend/requirements.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fastapi==0.95.0 # FastAPI version
|
||||||
|
uvicorn==0.22.0 # ASGI server
|
||||||
|
python-multipart==0.0.6 # For form data parsing
|
||||||
|
starlette # Compatible Starlette version with FastAPI 0.95.0
|
Loading…
Reference in New Issue
Block a user