diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..93be62c --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS files +.DS_Store +Thumbs.db + +# Logs +*.log + +# Temporary files +tmp/ +temp/ diff --git a/README.md b/README.md index dd35c2b..c0005c7 100644 --- a/README.md +++ b/README.md @@ -1 +1,182 @@ -# DailyFieldReport \ No newline at end of file +# Daily Construction Field Report + +A comprehensive web-based application for creating daily construction field reports. This tool helps construction inspectors, supervisors, and project managers document daily activities, track progress, and maintain accurate records of construction projects. + +## Features + +### Comprehensive Report Sections +- **Basic Information**: Date, time, project details, and inspector information +- **Weather Conditions**: Temperature and weather tracking +- **Work Performed**: Detailed description of daily activities with start/end times +- **Labor & Equipment**: Track workforce and equipment on site +- **Materials**: Document materials delivered and used +- **Issues & Delays**: Record problems, delays, and safety observations +- **Quality & Inspections**: Document inspections and quality concerns +- **Additional Notes**: Space for any other relevant information +- **Digital Signature**: Sign and date reports + +### Key Features +- ✅ **Required Field Validation**: Ensures critical information is captured +- 👁️ **Live Preview**: Preview reports before submission +- 🖨️ **Print Support**: Print-friendly format for physical copies +- 💾 **Auto-save Draft**: Automatically saves work in progress +- 📱 **Responsive Design**: Works on desktop, tablet, and mobile devices +- 🎨 **Modern UI**: Clean, professional interface with gradient styling +- 💿 **Local Storage**: Saves submitted reports locally (can be extended to server) + +## Getting Started + +### Prerequisites +- A modern web browser (Chrome, Firefox, Safari, or Edge) +- No installation or server required! + +### Usage + +1. **Open the Application** + ```bash + # Simply open index.html in your web browser + # On most systems, you can double-click the file + # Or use a command like: + open index.html # macOS + start index.html # Windows + xdg-open index.html # Linux + ``` + +2. **Fill Out the Report** + - Complete all required fields (marked with *) + - Fill in relevant sections for the day's activities + - Use the auto-save feature to prevent data loss + +3. **Preview Your Report** + - Click "Preview Report" to review your entries + - Make any necessary corrections + +4. **Submit the Report** + - Click "Submit Report" to save + - Reports are stored locally in your browser + - Option to create a new report after submission + +5. **Print or Export** + - Use the "Print Report" button from the preview + - Browser print dialog allows saving as PDF + +## Form Sections Explained + +### Basic Information +Required fields to identify the project and report: +- Report date and time +- Project name and location +- Contractor and inspector names + +### Weather Conditions +Important for construction scheduling and quality control: +- Temperature (°F) +- Weather conditions (clear, cloudy, rain, snow, etc.) + +### Work Performed Today +The heart of the report: +- Detailed description of all work completed +- Start and end times +- Progress made + +### Labor & Equipment +Track resources on site: +- Number of workers and supervisors +- Equipment used +- Subcontractors present + +### Materials +Document material flow: +- Materials delivered to site +- Materials used/installed +- Quantities and specifications + +### Issues, Delays & Observations +Critical for project management: +- Problems encountered +- Delays and their causes +- Safety observations and incidents + +### Quality & Inspections +Quality assurance documentation: +- Inspections performed +- Results and findings +- Quality issues or defects + +### Additional Notes +Any other relevant information not covered above + +### Signature +Digital signature to authenticate the report: +- Inspector's typed name +- Date of signature + +## Technical Details + +### Technology Stack +- **HTML5**: Semantic markup for accessibility +- **CSS3**: Modern styling with gradients and animations +- **JavaScript (Vanilla)**: No frameworks required, pure JavaScript for functionality + +### Browser Compatibility +- Chrome/Edge (latest) +- Firefox (latest) +- Safari (latest) +- Mobile browsers (iOS Safari, Chrome Mobile) + +### Data Storage +- Reports are stored in browser's localStorage +- Draft auto-save prevents data loss +- Can be extended to connect to a backend server/database + +## Customization + +### Adding Fields +To add new fields to the form: +1. Edit `index.html` to add the HTML input/textarea +2. Update `script.js` `displayPreview()` function to include the field in preview +3. Optionally update `styles.css` for custom styling + +### Changing Colors +Main color scheme is defined in `styles.css`: +- Primary gradient: `#667eea` to `#764ba2` +- Success color: `#27ae60` +- Error color: `#e74c3c` + +### Backend Integration +To save reports to a server: +1. Modify the `saveReport()` function in `script.js` +2. Add an API endpoint to receive form data +3. Replace localStorage with API calls + +## Screenshots + +The application features: +- Clean, modern interface with gradient header +- Organized sections for easy data entry +- Responsive design for all devices +- Professional preview and print layouts + +## Future Enhancements + +Potential improvements: +- PDF export functionality +- Photo upload capability +- Drawing/markup tools for site plans +- Email report functionality +- Cloud storage integration +- Multi-user support with authentication +- Report history and search +- Export to Excel/CSV + +## License + +This project is open source and available for use in construction projects. + +## Support + +For issues or questions, please open an issue on the GitHub repository. + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..e227d47 --- /dev/null +++ b/index.html @@ -0,0 +1,246 @@ + + + + + + Daily Construction Field Report + + + +
+
+

Daily Construction Field Report

+

Complete this form at the end of each working day

+
+ +
+ +
+

Basic Information

+ +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+
+ + +
+

Weather Conditions

+ +
+
+ + +
+
+ + +
+
+
+ + +
+

Work Performed Today

+ +
+ + +
+ +
+
+ + +
+
+ + +
+
+
+ + +
+

Labor & Equipment

+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ + +
+
+ + +
+

Materials

+ +
+ + +
+ +
+ + +
+
+ + +
+

Issues, Delays & Observations

+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ + +
+

Quality & Inspections

+ +
+ + +
+ +
+ + +
+
+ + +
+

Additional Notes

+ +
+ + +
+
+ + +
+

Signature

+ +
+
+ + +
+
+ + +
+
+
+ + +
+ + + +
+
+ + + + + +
+

✓ Report submitted successfully!

+
+
+ + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..08981e6 --- /dev/null +++ b/script.js @@ -0,0 +1,239 @@ +// Set default dates to today +document.addEventListener('DOMContentLoaded', function() { + const today = new Date(); + const dateString = today.toISOString().split('T')[0]; + const timeString = today.toTimeString().slice(0, 5); + + document.getElementById('reportDate').value = dateString; + document.getElementById('reportTime').value = timeString; + document.getElementById('signatureDate').value = dateString; +}); + +// Form submission handler +document.getElementById('fieldReportForm').addEventListener('submit', function(e) { + e.preventDefault(); + + if (validateForm()) { + // Collect form data + const formData = collectFormData(); + + // In a real application, you would send this data to a server + console.log('Form Data:', formData); + + // Save to localStorage for demo purposes + saveReport(formData); + + // Show success message + showSuccessMessage(); + + // Optionally reset form after a delay + setTimeout(() => { + if (confirm('Report submitted successfully! Would you like to create a new report?')) { + this.reset(); + // Reset dates to today + const today = new Date(); + const dateString = today.toISOString().split('T')[0]; + const timeString = today.toTimeString().slice(0, 5); + document.getElementById('reportDate').value = dateString; + document.getElementById('reportTime').value = timeString; + document.getElementById('signatureDate').value = dateString; + } + }, 2000); + } +}); + +// Form validation +function validateForm() { + const requiredFields = document.querySelectorAll('[required]'); + let isValid = true; + + requiredFields.forEach(field => { + if (!field.value.trim()) { + field.style.borderColor = '#e74c3c'; + isValid = false; + } else { + field.style.borderColor = '#ddd'; + } + }); + + if (!isValid) { + alert('Please fill in all required fields marked with *'); + } + + return isValid; +} + +// Collect form data +function collectFormData() { + const form = document.getElementById('fieldReportForm'); + const formData = new FormData(form); + const data = {}; + + for (let [key, value] of formData.entries()) { + data[key] = value; + } + + return data; +} + +// Save report to localStorage +function saveReport(data) { + const reports = JSON.parse(localStorage.getItem('dailyReports') || '[]'); + data.id = Date.now(); + data.submittedAt = new Date().toISOString(); + reports.push(data); + localStorage.setItem('dailyReports', JSON.stringify(reports)); +} + +// Show success message +function showSuccessMessage() { + const successMessage = document.getElementById('successMessage'); + successMessage.style.display = 'block'; + + setTimeout(() => { + successMessage.style.display = 'none'; + }, 3000); +} + +// Preview button handler +document.getElementById('previewBtn').addEventListener('click', function() { + if (validateForm()) { + const formData = collectFormData(); + displayPreview(formData); + document.getElementById('previewModal').style.display = 'block'; + } +}); + +// Display preview +function displayPreview(data) { + const previewContent = document.getElementById('previewContent'); + let html = ''; + + // Basic Information + html += '

Basic Information

'; + html += `

Date: ${data.reportDate || 'N/A'}

`; + html += `

Time: ${data.reportTime || 'N/A'}

`; + html += `

Project Name: ${data.projectName || 'N/A'}

`; + html += `

Project Location: ${data.projectLocation || 'N/A'}

`; + html += `

General Contractor: ${data.contractor || 'N/A'}

`; + html += `

Inspector Name: ${data.inspector || 'N/A'}

`; + + // Weather Conditions + html += '

Weather Conditions

'; + html += `

Temperature: ${data.temperature ? data.temperature + '°F' : 'N/A'}

`; + html += `

Conditions: ${data.weatherCondition || 'N/A'}

`; + + // Work Performed + html += '

Work Performed Today

'; + html += `

Description: ${data.workDescription || 'N/A'}

`; + html += `

Start Time: ${data.workStartTime || 'N/A'}

`; + html += `

End Time: ${data.workEndTime || 'N/A'}

`; + + // Labor & Equipment + html += '

Labor & Equipment

'; + html += `

Number of Workers: ${data.numWorkers || '0'}

`; + html += `

Number of Supervisors: ${data.numSupervisors || '0'}

`; + html += `

Equipment on Site: ${data.equipment || 'N/A'}

`; + html += `

Subcontractors Present: ${data.subcontractors || 'N/A'}

`; + + // Materials + html += '

Materials

'; + html += `

Materials Delivered: ${data.materialsDelivered || 'N/A'}

`; + html += `

Materials Used: ${data.materialsUsed || 'N/A'}

`; + + // Issues & Delays + html += '

Issues, Delays & Observations

'; + html += `

Issues/Problems: ${data.issues || 'None reported'}

`; + html += `

Delays: ${data.delays || 'None reported'}

`; + html += `

Safety Observations: ${data.safetyObservations || 'None reported'}

`; + + // Quality & Inspections + html += '

Quality & Inspections

'; + html += `

Inspections Performed: ${data.inspections || 'N/A'}

`; + html += `

Quality Issues: ${data.qualityIssues || 'None reported'}

`; + + // Additional Notes + html += '

Additional Notes

'; + html += `

${data.additionalNotes || 'No additional notes'}

`; + + // Signature + html += '

Signature

'; + html += `

Signed by: ${data.signatureName || 'N/A'}

`; + html += `

Date: ${data.signatureDate || 'N/A'}

`; + + previewContent.innerHTML = html; +} + +// Close modal handlers +document.querySelector('.close').addEventListener('click', function() { + document.getElementById('previewModal').style.display = 'none'; +}); + +document.getElementById('closePreviewBtn').addEventListener('click', function() { + document.getElementById('previewModal').style.display = 'none'; +}); + +// Close modal when clicking outside +window.addEventListener('click', function(event) { + const modal = document.getElementById('previewModal'); + if (event.target === modal) { + modal.style.display = 'none'; + } +}); + +// Print button handler +document.getElementById('printBtn').addEventListener('click', function() { + window.print(); +}); + +// Real-time field validation +document.querySelectorAll('input[required], textarea[required]').forEach(field => { + field.addEventListener('blur', function() { + if (!this.value.trim()) { + this.style.borderColor = '#e74c3c'; + } else { + this.style.borderColor = '#27ae60'; + } + }); + + field.addEventListener('input', function() { + if (this.value.trim()) { + this.style.borderColor = '#27ae60'; + } + }); +}); + +// Auto-save draft functionality (optional) +let autoSaveTimer; +document.getElementById('fieldReportForm').addEventListener('input', function() { + clearTimeout(autoSaveTimer); + autoSaveTimer = setTimeout(() => { + const formData = collectFormData(); + localStorage.setItem('draftReport', JSON.stringify(formData)); + console.log('Draft auto-saved'); + }, 2000); +}); + +// Load draft on page load if exists +window.addEventListener('load', function() { + const draft = localStorage.getItem('draftReport'); + if (draft) { + const shouldLoadDraft = confirm('A draft report was found. Would you like to load it?'); + if (shouldLoadDraft) { + const draftData = JSON.parse(draft); + loadFormData(draftData); + } else { + localStorage.removeItem('draftReport'); + } + } +}); + +// Load data into form +function loadFormData(data) { + Object.keys(data).forEach(key => { + const field = document.getElementById(key); + if (field) { + field.value = data[key]; + } + }); +} diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..103fc40 --- /dev/null +++ b/styles.css @@ -0,0 +1,362 @@ +/* Global Styles */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + line-height: 1.6; + color: #333; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + padding: 20px; +} + +.container { + max-width: 1000px; + margin: 0 auto; + background: white; + border-radius: 10px; + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2); + overflow: hidden; +} + +/* Header Styles */ +header { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 30px; + text-align: center; +} + +header h1 { + font-size: 2.5em; + margin-bottom: 10px; +} + +.subtitle { + font-size: 1.1em; + opacity: 0.9; +} + +/* Form Styles */ +form { + padding: 30px; +} + +.form-section { + margin-bottom: 40px; + padding-bottom: 30px; + border-bottom: 2px solid #e0e0e0; +} + +.form-section:last-of-type { + border-bottom: none; +} + +.form-section h2 { + color: #667eea; + font-size: 1.8em; + margin-bottom: 20px; + padding-bottom: 10px; + border-bottom: 3px solid #667eea; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; + margin-bottom: 20px; +} + +.form-group { + display: flex; + flex-direction: column; +} + +.form-group.full-width { + grid-column: 1 / -1; +} + +label { + font-weight: 600; + margin-bottom: 8px; + color: #444; + font-size: 0.95em; +} + +.required { + color: #e74c3c; + font-weight: bold; +} + +input[type="text"], +input[type="date"], +input[type="time"], +input[type="number"], +select, +textarea { + padding: 12px; + border: 2px solid #ddd; + border-radius: 5px; + font-size: 1em; + font-family: inherit; + transition: border-color 0.3s ease; + background-color: #fafafa; +} + +input[type="text"]:focus, +input[type="date"]:focus, +input[type="time"]:focus, +input[type="number"]:focus, +select:focus, +textarea:focus { + outline: none; + border-color: #667eea; + background-color: white; +} + +textarea { + resize: vertical; + min-height: 80px; +} + +select { + cursor: pointer; + appearance: none; + background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right 10px center; + background-size: 20px; + padding-right: 40px; +} + +/* Form Actions */ +.form-actions { + display: flex; + gap: 15px; + justify-content: center; + margin-top: 30px; + padding-top: 20px; + border-top: 2px solid #e0e0e0; +} + +.btn { + padding: 15px 30px; + border: none; + border-radius: 5px; + font-size: 1em; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.btn-primary { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4); +} + +.btn-secondary { + background: #f1f1f1; + color: #333; +} + +.btn-secondary:hover { + background: #e0e0e0; + transform: translateY(-2px); +} + +/* Modal Styles */ +.modal { + display: none; + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgba(0, 0, 0, 0.6); + animation: fadeIn 0.3s ease; +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +.modal-content { + background-color: white; + margin: 50px auto; + padding: 30px; + border-radius: 10px; + width: 90%; + max-width: 900px; + max-height: 80vh; + overflow-y: auto; + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); + animation: slideIn 0.3s ease; +} + +@keyframes slideIn { + from { + transform: translateY(-50px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +.close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; + cursor: pointer; + transition: color 0.3s ease; +} + +.close:hover, +.close:focus { + color: #000; +} + +.modal-actions { + display: flex; + gap: 15px; + justify-content: center; + margin-top: 30px; + padding-top: 20px; + border-top: 2px solid #e0e0e0; +} + +#previewContent { + line-height: 1.8; +} + +#previewContent h3 { + color: #667eea; + margin-top: 20px; + margin-bottom: 10px; + font-size: 1.3em; + border-bottom: 2px solid #667eea; + padding-bottom: 5px; +} + +#previewContent p { + margin-bottom: 10px; + padding-left: 10px; +} + +#previewContent strong { + color: #444; + display: inline-block; + min-width: 200px; +} + +/* Success Message */ +.success-message { + display: none; + position: fixed; + top: 20px; + right: 20px; + background: #27ae60; + color: white; + padding: 20px 30px; + border-radius: 5px; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); + z-index: 2000; + animation: slideInRight 0.3s ease; +} + +@keyframes slideInRight { + from { + transform: translateX(100%); + opacity: 0; + } + to { + transform: translateX(0); + opacity: 1; + } +} + +.success-message p { + font-size: 1.1em; + font-weight: 600; +} + +/* Responsive Design */ +@media (max-width: 768px) { + body { + padding: 10px; + } + + header h1 { + font-size: 1.8em; + } + + .subtitle { + font-size: 1em; + } + + .form-row { + grid-template-columns: 1fr; + gap: 15px; + } + + .form-actions { + flex-direction: column; + } + + .btn { + width: 100%; + } + + .modal-content { + width: 95%; + margin: 20px auto; + padding: 20px; + } + + .success-message { + right: 10px; + left: 10px; + } +} + +@media print { + body { + background: white; + padding: 0; + } + + .container { + box-shadow: none; + } + + header { + background: white; + color: #333; + } + + .form-actions, + .modal-actions, + .btn { + display: none; + } + + .form-section { + page-break-inside: avoid; + } +}