Spaces:
Sleeping
Sleeping
import gradio as gr | |
# List of apps with added Google Drive input links | |
apps = [ | |
{ | |
"name": "Auto DPR Generator", | |
"url": "https://huggingface.co/spaces/Rammohan0504/DPR-5", | |
"description": "Generates detailed progress reports based on uploaded site images, streamlining documentation.", | |
"input": "inputs DPR", | |
"drive_url": "https://drive.google.com/drive/folders/1w3FHuP6HOlKDur_r5lcnM8iXqBKdFors?usp=sharing" | |
}, | |
{ | |
"name": "AI Based Work Progress Verifier", | |
"url": "https://huggingface.co/spaces/Rekham1110/Construction_Project1", | |
"description": "Automatically detects construction milestones from site images and updates Salesforce with completion percentages and tags.", | |
"input": "Work Progress Verifier", | |
"drive_url": "https://drive.google.com/drive/folders/106UNEiyLKQu1aZfTFyXACdYY-_BYJlEg?usp=sharing" | |
}, | |
{ | |
"name": "Safety Violation CCTV AI Full", | |
"url": "https://huggingface.co/spaces/PrashanthB461/Safety_Violation_CCTV_AI", | |
"description": "Real-time detection of safety violations like missing helmets or unauthorized access, with alerts via Salesforce dashboard.", | |
"input": "Safety Violation", | |
"drive_url": "https://drive.google.com/drive/folders/1SfJWnUPU7lxSkPrAYiu4bqRFFl-cvChs?usp=sharing" | |
}, | |
{ | |
"name": "Material Reconciliation", | |
"url": "https://huggingface.co/spaces/VijayPulmamidi/MaterialReconciliationAI", | |
"description": "Tracks materials from purchase to usage, preventing waste, theft, or mismanagement.", | |
"input": "materialreconciliation", | |
"drive_url": "https://drive.google.com/drive/folders/1CFOC32FqxPhjLMUdPzUjH76uVSvtnbHL?usp=sharing" | |
}, | |
{ | |
"name": "Material Estimator", | |
"url": "https://kushalmanda-yolov5-blueprint-analysis.hf.space", | |
"description": "Provides accurate material estimations for construction projects based on blueprints and inputs.", | |
"input": "material estimator", | |
"drive_url": "https://drive.google.com/drive/folders/1WMWiqk7sw5Nn7YE9m0TFWcEvMY5Bje-A?usp=sharing" | |
}, | |
{ | |
"name": "AI Coach Site Supervisor", | |
"url": "https://huggingface.co/spaces/geethareddy/geethaAICoach3", | |
"description": "Generates daily checklists, milestone-based focus suggestions, and reflection logs for site supervisors.", | |
"input": "AI Coach Site Supervisor", | |
"drive_url": "https://drive.google.com/drive/folders/1M_IvEL3eezcIGlDMwOeyMubPIYOeWSGm?usp=sharing" | |
}, | |
{ | |
"name": "Smart Finishing Material Estimator", | |
"url": "https://huggingface.co/spaces/himabindug212/estimation_material", | |
"description": "Estimates quantities of finishing materials like tiles, paint, and panels with auto-calculated results.", | |
"input": "Smart Finisher Material Estimator", | |
"drive_url": "https://drive.google.com/drive/folders/167c5Ej-O1Hcl0UdXMmlMAbzrOOwllWnc?usp=sharing" | |
}, | |
{ | |
"name": "Labour Attendance Analyzer", | |
"url": "https://huggingface.co/spaces/lavanya121/attendance-forecasting_121", | |
"description": "Monitors labour attendance, identifies shortage risks, and suggests actionable solutions.", | |
"input": "Labour Attendance", | |
"drive_url": "https://drive.google.com/drive/folders/1sanCj7li9wGlX_VPJmIjdpPyOR-WQrmX?usp=sharing" | |
}, | |
{ | |
"name": "AI Estimator Daily Requirements", | |
"url": "https://huggingface.co/spaces/Naveensai/Construction-Forecast-App", | |
"description": "Forecasts daily labour and material requirements for efficient construction site management.", | |
"input": "AI Estimator Daily Requirements", | |
"drive_url": "https://drive.google.com/drive/folders/1fe3Bu0cPjMCTsQDaqBRI7TkqSs9105zP?usp=sharing" | |
}, | |
] | |
# Function to generate HTML content | |
def display_apps(search_query="", filter_input="All"): | |
# Filter apps based on search query and input category | |
filtered_apps = apps | |
if search_query: | |
filtered_apps = [ | |
app for app in filtered_apps | |
if search_query.lower() in app["name"].lower() or search_query.lower() in app["input"].lower() | |
] | |
if filter_input != "All": | |
filtered_apps = [app for app in filtered_apps if app["input"] == filter_input] | |
# Generate HTML with embedded CSS and JavaScript | |
html_content = """ | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> | |
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> | |
<style> | |
body { | |
font-family: 'Inter', sans-serif; | |
background: linear-gradient(135deg, #f3f4f6, #e5e7eb); | |
} | |
.card { | |
transition: transform 0.3s ease, box-shadow 0.3s ease; | |
margin-bottom: 20px; | |
} | |
.card:hover { | |
transform: translateY(-5px); | |
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); | |
} | |
.search-input, .filter-select { | |
transition: border-color 0.3s ease, box-shadow 0.3s ease; | |
} | |
.search-input:focus, .filter-select:focus { | |
border-color: #2563eb; | |
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); | |
} | |
.header { | |
animation: fadeIn 1s ease-in-out; | |
} | |
@keyframes fadeIn { | |
from { opacity: 0; transform: translateY(-20px); } | |
to { opacity: 1; transform: translateY(0); } | |
} | |
.button-container { | |
display: flex; | |
justify-content: center; | |
gap: 10px; | |
} | |
.launch-button, .drive-button { | |
background-color: transparent; | |
color: #2563eb; | |
border: 1px solid #2563eb; | |
padding: 5px 15px; | |
border-radius: 5px; | |
text-decoration: none; | |
transition: color 0.3s ease, border-color 0.3s ease; | |
} | |
.launch-button:hover, .drive-button:hover { | |
color: #1d4ed8; | |
border-color: #1d4ed8; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="min-h-screen py-12 px-4 sm:px-6 lg:px-8"> | |
<div class="max-w-7xl mx-auto"> | |
<div class="text-center mb-12 header"> | |
<h1 class="text-4xl font-bold text-gray-900">Construction Apps</h1> | |
</div> | |
<div id="apps-grid" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"> | |
""" | |
for app in filtered_apps: | |
html_content += f""" | |
<div class="card bg-white rounded-xl shadow-lg p-6"> | |
<h2 class="text-xl font-semibold text-blue-600 mb-3">{app['name']}</h2> | |
<p class="text-gray-600 mb-4">{app['description']}</p> | |
<p class="text-gray-500 italic mb-4"><span class="font-medium">Category:</span> {app['input']}</p> | |
<div class="button-container"> | |
<a href="{app['url']}" target="_blank" class="launch-button"> | |
Launch App | |
</a> | |
<a href="{app['drive_url']}" target="_blank" class="drive-button"> | |
View Input Data | |
</a> | |
</div> | |
</div> | |
""" | |
html_content += """ | |
</div> | |
</div> | |
</div> | |
<script> | |
document.addEventListener('DOMContentLoaded', () => { | |
const searchInput = document.getElementById('search-input'); | |
const filterInput = document.getElementById('filter-input'); | |
const appsGrid = document.getElementById('apps-grid'); | |
function renderApps() { | |
const searchQuery = searchInput ? searchInput.value.toLowerCase() : ''; | |
const filterValue = filterInput ? filterInput.value : 'All'; | |
let filteredApps = """ + str(apps).replace("'", '"') + """; | |
if (searchQuery) { | |
filteredApps = filteredApps.filter(app => | |
app.name.toLowerCase().includes(searchQuery) || | |
app.input.toLowerCase().includes(searchQuery) | |
); | |
} | |
if (filterValue !== "All") { | |
filteredApps = filteredApps.filter(app => app.input === filterValue); | |
} | |
appsGrid.innerHTML = filteredApps.length ? filteredApps.map(app => ` | |
<div class="card bg-white rounded-xl shadow-lg p-6"> | |
<h2 class="text-xl font-semibold text-blue-600 mb-3">\${app.name}</h2> | |
<p class="text-gray-600 mb-4">\${app.description}</p> | |
<p class="text-gray-500 italic mb-4"><span class="font-medium">Category:</span> \${app.input}</p> | |
<div class="button-container"> | |
<a href="\${app.url}" target="_blank" class="launch-button"> | |
Launch App | |
</a> | |
<a href="\${app.drive_url}" target="_blank" class="drive-button"> | |
View Input Data | |
</a> | |
</div> | |
</div> | |
`).join('') : '<p class="text-center text-gray-600 col-span-full">No apps found matching your criteria.</p>'; | |
} | |
if (searchInput && filterInput) { | |
searchInput.addEventListener('input', renderApps); | |
filterInput.addEventListener('change', renderApps); | |
renderApps(); | |
} | |
}); | |
</script> | |
</body> | |
</html> | |
""" | |
return html_content | |
# Gradio interface | |
with gr.Blocks(title="Construction Apps") as demo: | |
output = gr.HTML(display_apps("", "All")) | |
demo.launch() |