neerajkalyank's picture
Update app.py
df73753 verified
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()