Merge branch 'dev-anish' of http://gitea.lcepl.org/pjpatil12/Comparison_Project into dev-anish

This commit is contained in:
2026-02-02 14:57:20 +05:30
commit 37dd118cbd
57 changed files with 4063 additions and 0 deletions

217
app/templates/base.html Normal file
View File

@@ -0,0 +1,217 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ title if title else "Comparison Software" }}</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
</head>
<body class="bg-light">
<!-- NAVBAR -->
<!-- <nav class="navbar navbar-expand-lg navbar-dark bg-dark shadow-sm"> -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark shadow-sm fixed-top">
<div class="container-fluid">
<!-- Brand -->
<a class="navbar-brand fw-bold" href="/">
<i class="bi bi-buildings me-1"></i> LCEPL
</a>
<!-- Mobile toggle -->
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navMenu">
<span class="navbar-toggler-icon"></span>
</button>
<!-- Menu -->
<div class="collapse navbar-collapse" id="navMenu">
<ul class="navbar-nav ms-auto align-items-lg-center">
<!-- Dashboard -->
<li class="nav-item">
<a class="nav-link" href="/dashboard">
<<<<<<< HEAD
<i class="bi bi-speedometer2 me-1"></i> Dashboard-Anish
=======
<i class="bi bi-speedometer2 me-1"></i> Dashboard - Anish
>>>>>>> de8e68aff2a986814f5958a1f2faecb61acfd502
</a>
</li>
<!-- Subcontractor Model -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">
<i class="bi bi-people-fill me-1"></i> Subcontractor Model
</a>
<ul class="dropdown-menu dropdown-menu-dark">
<li>
<a class="dropdown-item" href="/subcontractor/add">
<i class="bi bi-plus-circle me-2"></i> Add Subcontractor
</a>
</li>
<li>
<a class="dropdown-item" href="/subcontractor/list">
<i class="bi bi-list-ul me-2"></i> Subcontractor List
</a>
</li>
</ul>
</li>
<!-- Subcontractor File System -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">
<i class="bi bi-folder-fill me-1"></i>Subcontractor File System
</a>
<ul class="dropdown-menu dropdown-menu-dark">
<li>
<a class="dropdown-item" href="/file/import_Subcontractor">
<i class="bi bi-upload me-2"></i> Import File
</a>
</li>
<li>
<a class="dropdown-item" href="/file/Subcontractor_report">
<i class="bi bi-download me-2"></i> Show Reports
</a>
</li>
<li>
<a class="dropdown-item" href="/dashboard/subcontractor_dashboard">
<i class="bi bi-speedometer2 me-2"></i> Subcontractor Dashboard
</a>
</li>
</ul>
</li>
<!-- Client System -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">
<i class="bi bi-building me-1"></i> Client File System
</a>
<ul class="dropdown-menu dropdown-menu-dark">
<li>
<a class="dropdown-item" href="/file/import_client">
<i class="bi bi-upload me-2"></i> Import Client File
</a>
</li>
<li>
<a class="dropdown-item" href="/file/client_report">
<i class="bi bi-arrow-left-right me-2"></i> Show Report
</a>
</li>
</ul>
</li>
<!-- Reports -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">
<i class="bi bi-building me-1"></i> Reports
</a>
<ul class="dropdown-menu dropdown-menu-dark">
<li>
<a class="dropdown-item" href="/report/comparison_report">
<i class="bi bi-arrow-left-right me-2"></i> client vs sub-cont. Comparison Report
</a>
</li>
<!-- <li>
<a class="dropdown-item" href="/file/client_vs_subcont">
<i class="bi bi-arrow-left-right me-2"></i> Comparison Report
</a>
</li> -->
</ul>
</li>
<!-- Formats -->
<li class="nav-item">
<a class="nav-link" href="/file_format">
<i class="bi bi-file-earmark-text me-1"></i> Formats
</a>
</li>
<!-- USER DROPDOWN -->
{% if session.get("user_id") %}
<li class="nav-item dropdown ms-lg-3">
<a class="nav-link dropdown-toggle d-flex align-items-center gap-2" href="#"
data-bs-toggle="dropdown">
<i class="bi bi-person-circle fs-5"></i>
<span class="d-none d-lg-inline">
{{ session.get("user_name") }}
</span>
</a>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-dark shadow">
<!-- User card -->
<li class="px-3 py-3 text-center border-bottom">
<i class="bi bi-person-circle fs-1"></i>
<div class="fw-semibold mt-1">
{{ session.get("user_name") }}
</div>
<small class="text-muted">Logged in user</small>
</li>
<li>
<a class="dropdown-item" href="/dashboard">
<i class="bi bi-speedometer2 me-2"></i> Dashboard
</a>
</li>
<li>
<a class="dropdown-item text-warning" href="/logout">
<i class="bi bi-box-arrow-right me-2"></i> Logout
</a>
</li>
</ul>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
<!-- PAGE CONTENT -->
<div class="container-fluid vh-100 pt-5 overflow-hidden">
<!-- FLASH MESSAGES -->
<div class="container mt-3">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }} alert-dismissible fade show">
{{ message }}
<button class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
</div>
<div class="overflow-auto h-100">
<div class="container mt-4">
{% block content %}{% endblock %}
</div>
</div>
</div>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,74 @@
{% extends "base.html" %}
{% block content %}
<div class="container-fluid mt-4">
<h2 class="mb-4">Client File Reports</h2>
<div class="card p-4 shadow-sm mb-5">
<form method="POST">
<label class="form-label fw-bold">RA Bill No</label>
<input type="text" name="RA_Bill_No" class="form-control mb-3" value="{{ ra_val }}" required>
<div class="row">
<div class="col-md-6">
<button type="submit" name="action" value="preview" class="btn btn-secondary w-100">Preview
Data</button>
</div>
<div class="col-md-6">
<button type="submit" name="action" value="download" class="btn btn-primary w-100">Download Excel
Report</button>
</div>
</div>
</form>
</div>
{% if tables.tr or tables.mh or tables.dc or tables.laying %}
<div class="card shadow-sm p-3">
<h4 class="mb-3">Comparison Preview</h4>
<ul class="nav nav-tabs" id="reportTabs" role="tablist">
<li class="nav-item">
<button class="nav-link active" id="tr-tab" data-bs-toggle="tab" data-bs-target="#tr"
type="button">Tr.Ex Comparison</button>
</li>
<li class="nav-item">
<button class="nav-link" id="mh-tab" data-bs-toggle="tab" data-bs-target="#mh" type="button">Mh.Ex
Comparison</button>
</li>
<li class="nav-item">
<button class="nav-link" id="dc-tab" data-bs-toggle="tab" data-bs-target="#dc" type="button">MH & DC
Comparison</button>
</li>
<li class="nav-item">
<button class="nav-link" id="laying-tab" data-bs-toggle="tab" data-bs-target="#laying"
type="button">Laying
& Bedding Comparison</button>
</ul>
<div class="tab-content mt-3" id="reportTabsContent">
<div class="tab-pane fade show active" id="tr" role="tabpanel">
<div class="table-responsive" style="max-height: 500px;">
{{ tables.tr|safe }}
</div>
</div>
<div class="tab-pane fade" id="mh" role="tabpanel">
<div class="table-responsive" style="max-height: 500px;">
{{ tables.mh|safe }}
</div>
</div>
<div class="tab-pane fade" id="dc" role="tabpanel">
<div class="table-responsive" style="max-height: 500px;">
{{ tables.dc|safe }}
</div>
</div>
<div class="tab-pane fade" id="laying" role="tabpanel">
<div class="table-responsive" style="max-height: 500px;">
{{ tables.laying|safe }}
</div>
</div>
</div>
{% endif %}
</div>
{% endblock %}

View File

@@ -0,0 +1,118 @@
{% extends "base.html" %}
{% block content %}
<div class="container-fluid px-2 px-md-4">
<h4 class="mb-3 text-center text-md-start">Comparison Software Solapur (UGD) - Live Dashboard</h4>
<div class="row g-3 mb-4">
<div class="col-12 col-md-4">
<div class="card text-white bg-primary shadow h-100">
<div class="card-body text-center text-md-start">
<h6>Trenching Units</h6>
<h3 class="fw-bold" id="card-trench">0</h3>
</div>
</div>
</div>
<div class="col-12 col-md-4">
<div class="card text-white bg-success shadow h-100">
<div class="card-body text-center text-md-start">
<h6>Manhole Units</h6>
<h3 class="fw-bold" id="card-manhole">0</h3>
</div>
</div>
</div>
<div class="col-12 col-md-4">
<div class="card text-dark bg-warning shadow h-100">
<div class="card-body text-center text-md-start">
<h6>Laying Units</h6>
<h3 class="fw-bold" id="card-laying">0</h3>
</div>
</div>
</div>
</div>
<div class="row g-3">
<div class="col-12 col-md-6">
<div class="card shadow-sm h-100">
<div class="card-header bg-dark text-white">Live Category Bar Chart</div>
<div class="card-body">
<canvas id="liveBarChart" style="max-height:300px;"></canvas>
</div>
</div>
</div>
<div class="col-12 col-md-6">
<div class="card shadow-sm h-100">
<div class="card-header bg-dark text-white">Location Distribution Pie Chart</div>
<div class="card-body">
<canvas id="livePieChart" style="max-height:300px;"></canvas>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
// 2. Initialize the Bar Chart
const barCtx = document.getElementById('liveBarChart').getContext('2d');
let liveBarChart = new Chart(barCtx, {
type: 'bar',
data: {
labels: ['Trenching', 'Manholes', 'Laying'],
datasets: [{
label: 'Units Completed',
data: [0, 0, 0],
backgroundColor: ['#0d6efd', '#198754', '#ffc107']
}]
},
options: { responsive: true, maintainAspectRatio: false }
});
// 3. Initialize the Pie Chart
const pieCtx = document.getElementById('livePieChart').getContext('2d');
let livePieChart = new Chart(pieCtx, {
type: 'pie',
data: {
labels: [], // Will be filled from SQL
datasets: [{
data: [],
backgroundColor: ['#0d6efd', '#198754', '#ffc107', '#6f42c1', '#fd7e14']
}]
},
options: { responsive: true, maintainAspectRatio: false }
});
// 4. Function to Fetch Live Data from your Python API
function fetchLiveData() {
fetch('/dashboard/api/live-stats') // This matches the route we created in the "Kitchen"
.then(response => response.json())
.then(data => {
// Update the Summary Cards
document.getElementById('card-trench').innerText = data.summary.trench;
document.getElementById('card-manhole').innerText = data.summary.manhole;
document.getElementById('card-laying').innerText = data.summary.laying;
// Update Bar Chart
liveBarChart.data.datasets[0].data = [
data.summary.trench,
data.summary.manhole,
data.summary.laying
];
liveBarChart.update();
// Update Pie Chart (Location stats)
livePieChart.data.labels = Object.keys(data.locations);
livePieChart.data.datasets[0].data = Object.values(data.locations);
livePieChart.update();
})
.catch(err => console.error("Error fetching live data:", err));
}
// 5. Check for updates every 10 seconds (Real-time effect)
setInterval(fetchLiveData, 10000);
fetchLiveData(); // Load immediately on page open
</script>
{% endblock %}

View File

@@ -0,0 +1,66 @@
{% extends "base.html" %}
{% block content %}
<h2 class="mb-4">Download File Formats</h2>
<div class="row g-4">
<!-- Subcontractor Format -->
<div class="col-md-4">
<div class="card text-center shadow-sm h-100">
<div class="card-body d-flex flex-column justify-content-center">
<div class="mb-3 fs-1 text-primary">
⬇️
</div>
<h5 class="card-title">Subcontractor Upload Format</h5>
<p class="text-muted mb-2">Excel (.xlsx)</p>
<p class="small text-secondary">File size: 245 KB</p>
<a href="{{ url_for('file_format.download_excel_format', filename='subcontractor_format.xlsx') }}"
class="btn btn-outline-primary mt-auto">
Download
</a>
</div>
</div>
</div>
<!-- Client Format -->
<div class="col-md-4">
<div class="card text-center shadow-sm h-100">
<div class="card-body d-flex flex-column justify-content-center">
<div class="mb-3 fs-1 text-success">
⬇️
</div>
<h5 class="card-title">Client Upload Format</h5>
<p class="text-muted mb-2">Excel (.xlsx)</p>
<p class="small text-secondary">File size: 310 KB</p>
<a href="{{ url_for('file_format.download_excel_format', filename='client_format.xlsx') }}"
class="btn btn-outline-success mt-auto">
Download
</a>
</div>
</div>
</div>
<!-- MH & DC Format -->
<!-- <div class="col-md-4">
<div class="card text-center shadow-sm h-100">
<div class="card-body d-flex flex-column justify-content-center">
<div class="mb-3 fs-1 text-warning">
⬇️
</div>
<h5 class="card-title">Manhole & DC Format</h5>
<p class="text-muted mb-2">Excel (.xlsx)</p>
<p class="small text-secondary">File size: 190 KB</p>
<a href="{{ url_for('file_format.download_excel_format', filename='mh_dc_format.xlsx') }}"
class="btn btn-outline-warning mt-auto">
Download
</a>
</div>
</div>
</div> -->
</div>
{% endblock %}

View File

@@ -0,0 +1,41 @@
{% extends "base.html" %}
{% block content %}
<h2 class="mb-4">Client File Import</h2>
<div class="card p-4 shadow-sm">
<form method="POST" enctype="multipart/form-data">
<!-- 1. SELECT SUBCONTRACTOR -->
<!-- <label class="form-label">Select Subcontractor vs Client</label>
<select name="subcontractor_id" id="subcontractor_id" class="form-select mb-3" required>
<option value="">-- Select Subcontractor --</option>
{% for sc in subcontractors %}
<option value="{{ sc.id }}">{{ sc.subcontractor_name }}</option>
{% endfor %}
</select> -->
<!-- 2. FILE TYPE (MODEL NAME) -->
<!-- <label class="form-label">Select File Type</label>
<select name="file_type" id="file_type" class="form-select mb-3" required>
<option value="">-- Select File Type --</option>
<option value="">Sheet</option>
<option value="tr_ex_client">Tr. Ex</option>
<option value="mh_ex_client">Mh. Ex </option>
<option value="mh_dc_client">MH & DC </option>
<option value="">Laying Sheet</option>
</select> -->
<label class="form-label">RA Bill No</label>
<input type="text" name="RA_Bill_No" class="form-control mb-3" required>
<!-- 3. FILE UPLOAD -->
<label class="form-label">Choose File</label>
<input type="file" name="file" class="form-control mb-3" required>
<button class="btn btn-primary w-100">Upload</button>
</form>
</div>
{% endblock %}

View File

@@ -0,0 +1,32 @@
{% extends "base.html" %}
{% block content %}
<h2 class="mb-4">Sub-Contractor File Import</h2>
<div class="card p-4 shadow-sm">
<form method="POST" enctype="multipart/form-data">
<!-- 1. SELECT SUBCONTRACTOR -->
<label class="form-label">Select Subcontractor</label>
<select name="subcontractor_id" id="subcontractor_id" class="form-select mb-3" required>
<option value="">-- Select Subcontractor --</option>
{% for sc in subcontractors %}
<option value="{{ sc.id }}">{{ sc.subcontractor_name }}</option>
{% endfor %}
</select>
<!-- 2. RA bill no -->
<label class="form-label">RA Bill No</label>
<input type="text" name="RA_Bill_No" class="form-control mb-3" required>
<!-- 3. FILE UPLOAD -->
<label class="form-label">Choose File</label>
<input type="file" name="file" class="form-control mb-3" required>
<button class="btn btn-primary w-100">Upload</button>
</form>
</div>
{% endblock %}

View File

@@ -0,0 +1,39 @@
{% extends "base.html" %}
{% block content %}
<div class="container mt-4">
<h2 class="mb-4">Subcontractor vs Client Comparison</h2>
<!-- FLASH MESSAGES -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
<div class="card p-4 shadow-sm">
<form method="POST">
<!-- SELECT SUBCONTRACTOR -->
<label class="form-label fw-semibold">Select Subcontractor</label>
<select name="subcontractor_id" id="subcontractor_id" class="form-select mb-3" required>
<option value="">-- Select Subcontractor --</option>
{% for sc in subcontractors %}
<option value="{{ sc.id }}">{{ sc.subcontractor_name }}</option>
{% endfor %}
</select>
<button class="btn btn-primary w-100">Generate Report</button>
</form>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,28 @@
{% extends "base.html" %}
{% block content %}
<h2 class="mb-4">Users List</h2>
<div class="card p-4 shadow-sm">
<table class="table table-bordered table-striped">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

82
app/templates/login.html Normal file
View File

@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LCEPL | Login</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container-fluid vh-100">
<div class="row h-100 justify-content-center align-items-center">
<!-- Increased column width -->
<div class="col-12 col-sm-10 col-md-8 col-lg-5 col-xl-4">
<div class="card shadow-lg border-0">
<!-- Increased padding -->
<div class="card-body p-5">
<!-- Branding -->
<div class="text-center mb-4">
<img src="{{ url_for('static', filename='images/lcepl.png') }}" alt="LCEPL Logo"
class="img-fluid mb-3" style="max-height:80px;">
<h4 class="fw-bold mb-1">
Laxmi Civil Engineering Services Pvt Ltd
</h4>
<p class="text-muted mb-0">
Data Comparison Software Solapur(UGD)
</p>
</div>
<!-- Flash messages -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
<!-- Login Form -->
<form method="POST">
<div class="mb-4">
<label class="form-label fw-semibold">User Name</label>
<input type="email" name="email" class="form-control " placeholder="Enter email"
required>
</div>
<div class="mb-4">
<label class="form-label fw-semibold">Password</label>
<input type="password" name="password" class="form-control" placeholder="Enter password"
required>
</div>
<button class="btn btn-success btn-lg w-100">
Login
</button>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,19 @@
{% extends "base.html" %}
{% block content %}
<h2>Register User</h2>
<div class="card p-4 shadow-sm">
<form method="POST">
<label>Name</label>
<input class="form-control mb-3" name="name" required>
<label>Email</label>
<input type="email" class="form-control mb-3" name="email" required>
<label>Password</label>
<input type="password" class="form-control mb-3" name="password" required>
<button class="btn btn-primary">Register</button>
</form>
</div>
{% endblock %}

View File

@@ -0,0 +1,40 @@
{% extends "base.html" %}
{% block content %}
<div class="card shadow-sm p-4">
<h4 class="mb-3">Add New Subcontractor</h4>
<form action="/subcontractor/save" method="POST">
<div class="mb-3">
<label class="form-label">Subcontractor Name</label>
<input type="text" class="form-control" name="subcontractor_name" required>
</div>
<div class="mb-3">
<label class="form-label">Contact Person Name</label>
<input type="text" class="form-control" name="contact_person">
</div>
<div class="mb-3">
<label class="form-label">Mobile</label>
<input type="text" class="form-control" name="mobile_no">
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input type="email" class="form-control" name="email_id">
</div>
<div class="mb-3">
<label class="form-label">GST No</label>
<input type="text" class="form-control" name="gst_no">
</div>
<button class="btn btn-success">Save</button>
</form>
</div>
{% endblock %}

View File

@@ -0,0 +1,41 @@
{% extends "base.html" %}
{% block content %}
<div class="card shadow-sm p-4">
<h4 class="mb-3">Edit Subcontractor</h4>
<form action="/subcontractor/update/{{ subcontractor.id }}" method="POST">
<div class="mb-3">
<label class="form-label">Subcontractor Name</label>
<input type="text" class="form-control" name="subcontractor_name"
value="{{ subcontractor.subcontractor_name }}" required>
</div>
<div class="mb-3">
<label class="form-label">Contact Person</label>
<input type="text" class="form-control" name="contact_person" value="{{ subcontractor.contact_person }}">
</div>
<div class="mb-3">
<label class="form-label">Mobile</label>
<input type="text" class="form-control" name="mobile_no" value="{{ subcontractor.mobile_no }}">
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input type="email" class="form-control" name="email_id" value="{{ subcontractor.email_id }}">
</div>
<div class="mb-3">
<label class="form-label">GST No</label>
<input type="text" class="form-control" name="gst_no" value="{{ subcontractor.gst_no }}">
</div>
<button class="btn btn-success">Update</button>
<a href="/subcontractor/list" class="btn btn-secondary">Back</a>
</form>
</div>
{% endblock %}

View File

@@ -0,0 +1,91 @@
{% extends "base.html" %}
{% block content %}
<div class="card shadow-sm p-3 p-md-4">
<!-- Header -->
<div class="row mb-3 align-items-center">
<div class="col-12 col-md-6 ">
<h4 class="mb-2 mb-md-0 text-center text-md-start">
Subcontractor List
</h4>
</div>
<div class="col-12 col-md-3 text-center text-md-end">
<a href="/subcontractor/add" class="btn btn-success w-100 w-md-auto">
Add Subcontractor
</a>
</div>
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped align-middle text-nowrap">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Name</th>
<th class="d-none d-md-table-cell">Mobile</th>
<th class="d-none d-lg-table-cell">Email</th>
<th class="d-none d-lg-table-cell">GST No</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
{% for s in subcontractors %}
<tr>
<td>{{ s.id }}</td>
<td class="fw-semibold text-wrap">
{{ s.subcontractor_name }}
</td>
<td class="d-none d-md-table-cell">
{{ s.mobile_no }}
</td>
<td class="d-none d-lg-table-cell">
{{ s.email_id }}
</td>
<td class="d-none d-lg-table-cell">
{{ s.gst_no }}
</td>
<!-- Action Buttons -->
<td class="text-center">
<div class="d-flex flex-column gap-1">
<a href="/subcontractor/edit/{{ s.id }}" class="btn btn-sm btn-warning">
Edit
</a>
<a href="/subcontractor/delete/{{ s.id }}" class="btn btn-sm btn-danger"
onclick="return confirm('Are you sure?')">
Delete
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
<!-- TOTAL ROW -->
<tfoot>
<tr class="table-secondary fw-bold">
<td colspan="2" class="text-end"> Total Subcontractors</td>
<td class="d-none d-lg-table-cell">-</td>
<td class="d-none d-lg-table-cell">-</td>
<td class="d-none d-lg-table-cell">-</td>
<td class="text-center">{{ subcontractors|length }}</td>
</tr>
</tfoot>
</table>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,29 @@
{% extends "base.html" %}
{% block content %}
<div class="container-fluid px-2 px-md-4">
<h4 class="mb-3 text-center text-md-start">Subcontractor Dashboard </h4>
<!-- Charts -->
<div class="row g-3">
<!-- Bar Chart -->
<div class="col-12 col-md-6">
<div class="card shadow-sm h-100">
<div class="card-header bg-dark text-white text-center text-md-start">
Work Category Bar Chart
</div>
<div class="card-body text-center">
<img src="data:image/png;base64,{{ bar_chart }}" class="img-fluid" style="max-height:300px;">
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,142 @@
{% extends "base.html" %}
{% block content %}
<div class="container my-4">
<h2 class="text-center mb-4">Generate Subcontractor Report</h2>
<!-- FORM -->
<div class="card shadow-sm p-3 p-md-4 mx-auto" style="max-width:600px;">
<form method="POST">
<div class="mb-3">
<label class="form-label fw-semibold">Select Subcontractor</label>
<select name="subcontractor_id" class="form-select" required>
<option value="">-- Select Subcontractor --</option>
{% for sc in subcontractors %}
<option value="{{ sc.id }}" {% if selected_sc_id==sc.id|string %}selected{% endif %}>
{{ sc.subcontractor_name }}
</option>
{% endfor %}
</select>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="downloadAllSwitch" name="download_all" value="true"
{% if download_all %}checked{% endif %}>
<label class="form-check-label fw-bold text-primary">
Download All RA Bills
</label>
</div>
<div class="mb-4" id="ra_bill_container">
<label class="form-label fw-semibold">RA Bill Number</label>
<input type="text" name="ra_bill_no" id="ra_bill_input" class="form-control"
value="{{ ra_bill_no or '' }}">
</div>
<div class="row g-2">
<div class="col-12 col-md-6">
<button class="btn btn-outline-primary w-100" name="action" value="preview">
Preview Data
</button>
</div>
<div class="col-12 col-md-6">
<button class="btn btn-primary w-100" name="action" value="download">
Download Excel
</button>
</div>
</div>
</form>
</div>
{% if tables %}
<!-- REPORT PREVIEW -->
<div class="mt-5">
<h3 class="text-center mb-3">Report Preview</h3>
<div class="card shadow-sm">
<!-- MOBILE SCROLLABLE TABS -->
<div class="card-header p-0">
<ul class="nav nav-tabs flex-nowrap overflow-auto">
<li class="nav-item">
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tr">
Trench Excavation
</button>
</li>
<li class="nav-item">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#mh">
Manhole Excavation
</button>
</li>
<li class="nav-item">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#dc">
Manhole & Domestic Chambers
</button>
</li>
<li class="nav-item">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#laying">
Pipe Laying
</button>
</li>
</ul>
</div>
<!-- TAB CONTENT -->
<div class="card-body tab-content">
<div class="tab-pane fade show active" id="tr">
<div class="table-responsive overflow-auto">
{{ tables.tr | safe }}
</div>
</div>
<div class="tab-pane fade" id="mh">
<div class="table-responsive overflow-auto">
{{ tables.mh | safe }}
</div>
</div>
<div class="tab-pane fade" id="dc">
<div class="table-responsive overflow-auto">
{{ tables.dc | safe }}
</div>
</div>
<div class="tab-pane fade" id="laying">
<div class="table-responsive overflow-auto">
{{ tables.laying | safe }}
</div>
</div>
</div>
</div>
</div>
{% endif %}
</div>
<!-- BOOTSTRAP-ONLY JS -->
<script>
function toggleRAInput() {
const checkbox = document.getElementById("downloadAllSwitch");
const input = document.getElementById("ra_bill_input");
const container = document.getElementById("ra_bill_container");
if (checkbox.checked) {
input.value = "";
input.disabled = true;
container.classList.add("opacity-50");
} else {
input.disabled = false;
container.classList.remove("opacity-50");
}
}
document.addEventListener("DOMContentLoaded", toggleRAInput);
document.getElementById("downloadAllSwitch").addEventListener("change", toggleRAInput);
</script>
{% endblock %}

28
app/templates/users.htm Normal file
View File

@@ -0,0 +1,28 @@
{% extends "base.html" %}
{% block content %}
<h2 class="mb-4">Users List</h2>
<div class="card p-4 shadow-sm">
<table class="table table-bordered table-striped">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}