File size: 10,421 Bytes
d11e7ac
 
df73753
d11e7ac
 
 
 
 
df73753
 
d11e7ac
 
 
 
 
df73753
 
d11e7ac
 
 
 
 
df73753
 
d11e7ac
 
 
 
 
df73753
 
d11e7ac
 
 
 
 
df73753
 
d11e7ac
 
 
 
 
df73753
 
d11e7ac
 
 
 
 
df73753
 
d11e7ac
 
 
 
 
df73753
 
d11e7ac
 
 
 
 
df73753
 
d11e7ac
 
 
c39fccd
d11e7ac
 
 
 
 
 
 
 
 
 
 
4f62622
d11e7ac
4f62622
 
d11e7ac
4f62622
 
d11e7ac
 
 
c39fccd
d11e7ac
 
c39fccd
 
d11e7ac
c39fccd
 
 
d11e7ac
 
c39fccd
 
d11e7ac
c39fccd
 
d11e7ac
 
c39fccd
 
d11e7ac
c39fccd
 
 
 
 
 
 
 
df73753
c39fccd
df73753
57de375
 
 
 
 
 
 
 
df73753
57de375
 
 
d11e7ac
 
 
 
 
 
df73753
d11e7ac
 
c39fccd
8ba14db
d11e7ac
 
 
 
 
 
c39fccd
57de375
c39fccd
 
df73753
 
 
c39fccd
6d00ffc
d11e7ac
8ba14db
d11e7ac
 
8ba14db
 
d11e7ac
 
 
 
 
f7fc2bd
d11e7ac
c39fccd
 
d11e7ac
6d00ffc
d11e7ac
 
 
 
 
 
6d00ffc
d11e7ac
 
 
6d00ffc
d11e7ac
 
df73753
 
 
c39fccd
df73753
c39fccd
 
df73753
 
 
c39fccd
d11e7ac
 
3bec4c1
 
c39fccd
 
 
 
 
d11e7ac
 
 
 
 
4f62622
d11e7ac
8ba14db
d11e7ac
4f62622
 
c39fccd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
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()