basic poc

This commit is contained in:
mik-tf 2024-09-05 20:59:46 -04:00
parent a374549fa1
commit 8591ec376b
16 changed files with 286 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Virtual Environment Directories
venv/
__pycache__/

25
backend/README.md Normal file
View 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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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
View 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
View 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