Compare commits
9
Commits
f668a54e5f
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79b3edf8cd | ||
|
|
34b6b89b12 | ||
|
|
2980fcf509 | ||
|
|
b4fff79eda | ||
|
|
b552f27f52 | ||
|
|
e0654429dc | ||
|
|
6f28a9e40c | ||
|
|
7762c9f308 | ||
|
|
d79f806c59 |
+4
-13
@@ -1,15 +1,6 @@
|
|||||||
# Python
|
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
*$py.class
|
|
||||||
venv/
|
venv/
|
||||||
|
__pycache__/
|
||||||
# Uploads
|
*.pyc
|
||||||
uploads/
|
*.log
|
||||||
|
|
||||||
# IDE
|
|
||||||
.vscode/
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
# OS
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.env
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
# IT Site Survey AI
|
||||||
|
|
||||||
|
A complete single-page web application for conducting IT infrastructure site surveys with AI-powered analysis and recommendations.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### 1. Surveys List Tab
|
||||||
|
- View all created surveys with metadata (name, client, site, date)
|
||||||
|
- Click any survey to view and analyze
|
||||||
|
- Delete individual surveys with confirmation
|
||||||
|
- Clear all surveys with confirmation
|
||||||
|
- Empty state with quick action to create first survey
|
||||||
|
|
||||||
|
### 2. Create Survey Tab
|
||||||
|
- **Metadata Fields**: Survey name, client name, site location, description
|
||||||
|
- **Model Selector**: Choose from GPT-4o, GPT-4o Mini, Claude 3.5 Sonnet, Claude 3 Opus, Gemini 1.5 Pro
|
||||||
|
- **35 Survey Questions**: Comprehensive IT infrastructure questions organized by category:
|
||||||
|
- General Information
|
||||||
|
- Infrastructure
|
||||||
|
- Networking
|
||||||
|
- Security
|
||||||
|
- Cloud
|
||||||
|
- Applications
|
||||||
|
- Compliance
|
||||||
|
- IT Operations
|
||||||
|
- Future Planning
|
||||||
|
- **Load Sample Data**: Button to fill all fields with realistic test data
|
||||||
|
- **Photo Upload**: Drag-and-drop photo upload with preview
|
||||||
|
- **Submit**: Creates survey and redirects to surveys list
|
||||||
|
|
||||||
|
### 3. AI Analysis Tab
|
||||||
|
- **Survey Details Panel**: Shows client, site, creation date, description
|
||||||
|
- **Questions Summary**: Shows answered/total count per category
|
||||||
|
- **Model Selector**: Choose AI model for analysis
|
||||||
|
- **Generate Recommendations**: Streaming AI analysis with:
|
||||||
|
- Executive Summary
|
||||||
|
- Critical Findings
|
||||||
|
- Immediate Actions
|
||||||
|
- Short-term Initiatives
|
||||||
|
- Strategic Roadmap
|
||||||
|
- Resource Planning
|
||||||
|
- Compliance Considerations
|
||||||
|
- **Export Options**: Text, JSON (PDF placeholder), Email
|
||||||
|
- **Chat Interface**: Ask AI questions about the survey
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
| Method | Endpoint | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| GET | `/api/models` | Get available AI models |
|
||||||
|
| GET | `/api/surveys/template` | Get 35-question survey template |
|
||||||
|
| GET | `/api/surveys` | List all surveys |
|
||||||
|
| POST | `/api/surveys` | Create new survey |
|
||||||
|
| GET | `/api/surveys/{id}` | Get specific survey |
|
||||||
|
| PUT | `/api/surveys/{id}` | Update survey |
|
||||||
|
| DELETE | `/api/surveys/{id}` | Delete survey |
|
||||||
|
| DELETE | `/api/surveys` | Delete all surveys |
|
||||||
|
| POST | `/api/surveys/{id}/analyze` | Generate AI analysis (streaming) |
|
||||||
|
| POST | `/api/surveys/{id}/chat` | Chat about survey |
|
||||||
|
| POST | `/api/surveys/{id}/export` | Export survey report |
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create virtual environment
|
||||||
|
python3 -m venv venv
|
||||||
|
|
||||||
|
# Activate virtual environment
|
||||||
|
source venv/bin/activate # On Windows: venv\Scripts\activate
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running the Application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Default port (5000)
|
||||||
|
python app.py
|
||||||
|
|
||||||
|
# Custom port
|
||||||
|
python app.py 8080
|
||||||
|
```
|
||||||
|
|
||||||
|
Then open `http://localhost:5000` (or your custom port) in a web browser.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
site-survey-ai-v2/
|
||||||
|
├── app.py # Flask backend API
|
||||||
|
├── requirements.txt # Python dependencies
|
||||||
|
├── README.md # This file
|
||||||
|
├── static/
|
||||||
|
│ ├── style.css # Dark theme styling
|
||||||
|
│ └── app.js # Frontend application
|
||||||
|
└── templates/
|
||||||
|
└── index.html # Single-page app template
|
||||||
|
```
|
||||||
|
|
||||||
|
## Technologies Used
|
||||||
|
|
||||||
|
- **Backend**: Python Flask
|
||||||
|
- **Frontend**: Vanilla JavaScript (no frameworks)
|
||||||
|
- **Styling**: CSS3 with CSS variables for theming
|
||||||
|
- **API**: RESTful JSON API with streaming support
|
||||||
|
|
||||||
|
## Browser Compatibility
|
||||||
|
|
||||||
|
- Chrome 90+
|
||||||
|
- Firefox 88+
|
||||||
|
- Safari 14+
|
||||||
|
- Edge 90+
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License
|
||||||
+578
-1111
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
|||||||
|
Flask==2.3.3
|
||||||
|
Flask-CORS==4.0.0
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# IT Site Survey AI - Startup Script
|
||||||
|
|
||||||
|
# Check if virtual environment exists
|
||||||
|
if [ ! -d "venv" ]; then
|
||||||
|
echo "Creating virtual environment..."
|
||||||
|
python3 -m venv venv
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Activate virtual environment
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
# Install dependencies if needed
|
||||||
|
echo "Checking dependencies..."
|
||||||
|
pip install -q -r requirements.txt
|
||||||
|
|
||||||
|
# Get port from argument or default to 5000
|
||||||
|
PORT=${1:-5000}
|
||||||
|
|
||||||
|
echo "Starting IT Site Survey AI on port $PORT..."
|
||||||
|
echo "Open http://localhost:$PORT in your browser"
|
||||||
|
echo ""
|
||||||
|
echo "Press Ctrl+C to stop"
|
||||||
|
|
||||||
|
# Start the application
|
||||||
|
python app.py $PORT
|
||||||
+1129
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,991 @@
|
|||||||
|
/* IT Site Survey AI - Dark Theme Styles */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--bg-primary: #0f172a;
|
||||||
|
--bg-secondary: #1e293b;
|
||||||
|
--bg-tertiary: #334155;
|
||||||
|
--bg-hover: #475569;
|
||||||
|
--text-primary: #f1f5f9;
|
||||||
|
--text-secondary: #94a3b8;
|
||||||
|
--text-muted: #64748b;
|
||||||
|
--accent-primary: #6366f1;
|
||||||
|
--accent-primary-hover: #4f46e5;
|
||||||
|
--accent-secondary: #22d3ee;
|
||||||
|
--success: #10b981;
|
||||||
|
--warning: #f59e0b;
|
||||||
|
--danger: #ef4444;
|
||||||
|
--danger-hover: #dc2626;
|
||||||
|
--border-color: #334155;
|
||||||
|
--border-radius: 8px;
|
||||||
|
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3);
|
||||||
|
--shadow: 0 4px 6px -1px rgb(0 0 0 / 0.4);
|
||||||
|
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.5);
|
||||||
|
--transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.6;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* App Container */
|
||||||
|
.app-container {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header */
|
||||||
|
.app-header {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tab Navigation */
|
||||||
|
.tab-nav {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
padding: 0.25rem;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn {
|
||||||
|
padding: 0.625rem 1.25rem;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn:hover {
|
||||||
|
color: var(--text-primary);
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn.active {
|
||||||
|
background: var(--accent-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main Content */
|
||||||
|
.app-main {
|
||||||
|
flex: 1;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tab Content */
|
||||||
|
.tab-content {
|
||||||
|
display: none;
|
||||||
|
animation: fadeIn 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-content.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(10px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section Header */
|
||||||
|
.section-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header h2 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
.btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.625rem 1rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background: var(--accent-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background: var(--accent-primary-hover);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background: var(--bg-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger {
|
||||||
|
background: var(--danger);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger:hover {
|
||||||
|
background: var(--danger-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-small {
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-large {
|
||||||
|
padding: 0.875rem 2rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Surveys Grid */
|
||||||
|
.surveys-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Empty State */
|
||||||
|
.empty-state {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 4rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state svg {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state p {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Survey Card */
|
||||||
|
.survey-card {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.survey-card:hover {
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.survey-card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-badge {
|
||||||
|
background: var(--success);
|
||||||
|
color: white;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.survey-card h3 {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.survey-card-meta {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.survey-card-meta span {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.survey-card-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-delete-card {
|
||||||
|
background: transparent;
|
||||||
|
color: var(--danger);
|
||||||
|
border: 1px solid var(--danger);
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-delete-card:hover {
|
||||||
|
background: var(--danger);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Form Styles */
|
||||||
|
.survey-form {
|
||||||
|
max-width: 900px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 1.5rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section h3 {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-count {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row .form-group {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label::after {
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label[for]:has(+ [required])::after,
|
||||||
|
.form-group label:has(+ [required])::after {
|
||||||
|
content: ' *';
|
||||||
|
color: var(--danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input[type="text"],
|
||||||
|
.form-group input[type="email"],
|
||||||
|
.form-group select,
|
||||||
|
.form-group textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.625rem 0.875rem;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input:focus,
|
||||||
|
.form-group select:focus,
|
||||||
|
.form-group textarea:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group textarea {
|
||||||
|
resize: vertical;
|
||||||
|
min-height: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group select option {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-submit-section {
|
||||||
|
text-align: center;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Questions Container */
|
||||||
|
.questions-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-item {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-number {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--accent-primary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-category {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-text {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-input input[type="text"],
|
||||||
|
.question-input select,
|
||||||
|
.question-input textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.625rem 0.875rem;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-input textarea {
|
||||||
|
min-height: 80px;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-input input:focus,
|
||||||
|
.question-input select:focus,
|
||||||
|
.question-input textarea:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Photo Upload */
|
||||||
|
.photo-upload-area {
|
||||||
|
border: 2px dashed var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-upload-area:hover {
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
background: rgba(99, 102, 241, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-upload-area.dragover {
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
background: rgba(99, 102, 241, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-upload-area svg {
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-upload-area p {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-preview-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-preview-item {
|
||||||
|
position: relative;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-preview-item img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-preview-remove {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.25rem;
|
||||||
|
right: 0.25rem;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--danger);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Analysis Layout */
|
||||||
|
.analysis-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-back {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-select {
|
||||||
|
padding: 0.625rem 1rem;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-layout {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 320px 1fr;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.analysis-layout {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Panel */
|
||||||
|
.panel {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 1.25rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel h4 {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header h4 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Survey Meta List */
|
||||||
|
.survey-meta-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta-label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta-value {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Question Summary */
|
||||||
|
.question-summary {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-summary-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.5rem;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-summary-item .category {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-summary-item .count {
|
||||||
|
color: var(--accent-primary);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Analysis Output */
|
||||||
|
.analysis-output-panel {
|
||||||
|
min-height: 400px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-output {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-placeholder {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
text-align: center;
|
||||||
|
padding: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-placeholder svg {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-content {
|
||||||
|
line-height: 1.8;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-content h1,
|
||||||
|
.analysis-content h2,
|
||||||
|
.analysis-content h3,
|
||||||
|
.analysis-content h4 {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-content h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-content h2 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-content h3 {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
color: var(--accent-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-content p {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-content ul,
|
||||||
|
.analysis-content ol {
|
||||||
|
margin-left: 1.5rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-content li {
|
||||||
|
margin-bottom: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-content strong {
|
||||||
|
color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-content hr {
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Analysis Loading */
|
||||||
|
.analysis-loading {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 3rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border: 3px solid var(--border-color);
|
||||||
|
border-top-color: var(--accent-primary);
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Chat Panel */
|
||||||
|
.chat-panel {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-messages {
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
padding-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-message {
|
||||||
|
padding: 0.875rem 1rem;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
max-width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-message.system {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
align-self: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-message.user {
|
||||||
|
background: var(--accent-primary);
|
||||||
|
color: white;
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-message.assistant {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-message p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-input-area {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-input-area input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-input-area input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-input-area input:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Export Buttons */
|
||||||
|
.export-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modal */
|
||||||
|
.modal {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
position: relative;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 1.5rem;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 400px;
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content h3 {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content p {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toast */
|
||||||
|
.toast {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 2rem;
|
||||||
|
right: 2rem;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
z-index: 1001;
|
||||||
|
animation: slideIn 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast.success {
|
||||||
|
border-left: 4px solid var(--success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast.error {
|
||||||
|
border-left: 4px solid var(--danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideIn {
|
||||||
|
from {
|
||||||
|
transform: translateX(100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.app-header {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-main {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.surveys-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-header {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-title {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-controls {
|
||||||
|
width: 100%;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scrollbar Styling */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--bg-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Selection */
|
||||||
|
::selection {
|
||||||
|
background: var(--accent-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>IT Site Survey AI</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- Header -->
|
||||||
|
<header class="app-header">
|
||||||
|
<div class="logo">
|
||||||
|
<img src="/static/logo.png" alt="BeawIT Logo" style="height: 40px; margin-right: 10px;">
|
||||||
|
<h1>Network Site Survey AI</h1>
|
||||||
|
</div>
|
||||||
|
<nav class="tab-nav">
|
||||||
|
<button class="tab-btn active" data-tab="surveys" id="nav-surveys">Surveys List</button>
|
||||||
|
<button class="tab-btn" data-tab="create" id="nav-create">Create Survey</button>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<main class="app-main">
|
||||||
|
<!-- Surveys List Tab -->
|
||||||
|
<section class="tab-content active" id="tab-surveys">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2>Site Surveys</h2>
|
||||||
|
<button class="btn btn-danger" id="btn-clear-all">Clear All</button>
|
||||||
|
</div>
|
||||||
|
<div class="surveys-grid" id="surveys-list">
|
||||||
|
<div class="empty-state">
|
||||||
|
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||||
|
<path d="M9 12h.01M15 12h.01M10 16c.5.3 1.2.5 2 .5s1.5-.2 2-.5M22 12c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2s10 4.477 10 10z"/>
|
||||||
|
</svg>
|
||||||
|
<p>No surveys yet. Create your first survey!</p>
|
||||||
|
<button class="btn btn-primary" onclick="switchTab('create')">Create Survey</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Create Survey Tab -->
|
||||||
|
<section class="tab-content" id="tab-create">
|
||||||
|
<form id="survey-form" class="survey-form">
|
||||||
|
<!-- Metadata Section -->
|
||||||
|
<div class="form-section">
|
||||||
|
<h3>Survey Information</h3>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="survey-name">Survey Name *</label>
|
||||||
|
<input type="text" id="survey-name" name="name" required placeholder="e.g., Q3 Infrastructure Assessment">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="survey-client">Client Name *</label>
|
||||||
|
<input type="text" id="survey-client" name="client" required placeholder="e.g., Acme Corporation">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="survey-site">Site Location *</label>
|
||||||
|
<input type="text" id="survey-site" name="site" required placeholder="e.g., Main HQ - San Francisco">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="survey-model">AI Model</label>
|
||||||
|
<select id="survey-model" name="model">
|
||||||
|
<option value="">Loading models...</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="survey-description">Description</label>
|
||||||
|
<textarea id="survey-description" name="description" rows="3" placeholder="Brief description of the survey purpose..."></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-actions">
|
||||||
|
<button type="button" class="btn btn-secondary" id="btn-load-sample">Load Sample Data</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Questions Section -->
|
||||||
|
<div class="form-section">
|
||||||
|
<h3>Survey Questions <span class="question-count" id="question-count">(0/35)</span></h3>
|
||||||
|
<div class="questions-container" id="questions-container">
|
||||||
|
<!-- Questions loaded dynamically -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Photos Section -->
|
||||||
|
<div class="form-section">
|
||||||
|
<h3>Site Photos</h3>
|
||||||
|
<div class="photo-upload-area" id="photo-upload-area">
|
||||||
|
<input type="file" id="photo-input" accept="image/*" multiple hidden>
|
||||||
|
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||||
|
<path d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||||||
|
</svg>
|
||||||
|
<p>Drag and drop photos here or click to browse</p>
|
||||||
|
<button type="button" class="btn btn-secondary" id="btn-browse-photos">Browse Photos</button>
|
||||||
|
</div>
|
||||||
|
<div class="photo-preview-grid" id="photo-preview-grid"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Submit Section -->
|
||||||
|
<div class="form-section form-submit-section">
|
||||||
|
<button type="submit" class="btn btn-primary btn-large" id="btn-submit-survey">Create Survey</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Analysis Tab (shown when viewing a survey) -->
|
||||||
|
<section class="tab-content" id="tab-analysis">
|
||||||
|
<div class="analysis-header">
|
||||||
|
<div class="analysis-title">
|
||||||
|
<button class="btn btn-secondary btn-back" id="btn-back-to-surveys">
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M19 12H5M12 19l-7-7 7-7"/>
|
||||||
|
</svg>
|
||||||
|
Back
|
||||||
|
</button>
|
||||||
|
<h2 id="analysis-survey-name">Survey Analysis</h2>
|
||||||
|
</div>
|
||||||
|
<div class="analysis-controls">
|
||||||
|
<select id="analysis-model" class="model-select">
|
||||||
|
<option value="">Loading models...</option>
|
||||||
|
</select>
|
||||||
|
<button class="btn btn-primary" id="btn-generate-analysis">Generate Recommendations</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="analysis-layout">
|
||||||
|
<!-- Survey Summary Panel -->
|
||||||
|
<div class="analysis-sidebar">
|
||||||
|
<div class="panel">
|
||||||
|
<h4>Survey Details</h4>
|
||||||
|
<div class="survey-meta-list" id="analysis-survey-meta">
|
||||||
|
<!-- Populated dynamically -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel">
|
||||||
|
<h4>Questions Summary</h4>
|
||||||
|
<div class="question-summary" id="analysis-question-summary">
|
||||||
|
<!-- Populated dynamically -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Analysis Output Panel -->
|
||||||
|
<div class="analysis-main">
|
||||||
|
<div class="panel analysis-output-panel">
|
||||||
|
<div class="panel-header">
|
||||||
|
<h4>AI Analysis</h4>
|
||||||
|
<div class="export-buttons" id="export-buttons" style="display: none;">
|
||||||
|
<button class="btn btn-secondary btn-small" id="btn-export-text">Export Text</button>
|
||||||
|
<button class="btn btn-secondary btn-small" id="btn-export-pdf">Export PDF</button>
|
||||||
|
<button class="btn btn-secondary btn-small" id="btn-email">Email</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="analysis-output" id="analysis-output">
|
||||||
|
<div class="analysis-placeholder">
|
||||||
|
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||||
|
<path d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/>
|
||||||
|
</svg>
|
||||||
|
<p>Click "Generate Recommendations" to get AI-powered insights</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="analysis-loading" id="analysis-loading" style="display: none;">
|
||||||
|
<div class="spinner"></div>
|
||||||
|
<p>Analyzing survey data...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Chat Interface -->
|
||||||
|
<div class="panel chat-panel">
|
||||||
|
<div class="panel-header">
|
||||||
|
<h4>Ask AI About This Survey</h4>
|
||||||
|
</div>
|
||||||
|
<div class="chat-messages" id="chat-messages">
|
||||||
|
<div class="chat-message system">
|
||||||
|
<p>Ask me anything about this survey - budget planning, security recommendations, timeline suggestions, or technical details!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chat-input-area">
|
||||||
|
<input type="text" id="chat-input" placeholder="Type your question..." disabled>
|
||||||
|
<button class="btn btn-primary" id="btn-send-chat" disabled>
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delete Confirmation Modal -->
|
||||||
|
<div class="modal" id="delete-modal" style="display: none;">
|
||||||
|
<div class="modal-overlay"></div>
|
||||||
|
<div class="modal-content">
|
||||||
|
<h3>Delete Survey?</h3>
|
||||||
|
<p>Are you sure you want to delete this survey? This action cannot be undone.</p>
|
||||||
|
<div class="modal-actions">
|
||||||
|
<button class="btn btn-secondary" id="btn-cancel-delete">Cancel</button>
|
||||||
|
<button class="btn btn-danger" id="btn-confirm-delete">Delete</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Clear All Confirmation Modal -->
|
||||||
|
<div class="modal" id="clear-all-modal" style="display: none;">
|
||||||
|
<div class="modal-overlay"></div>
|
||||||
|
<div class="modal-content">
|
||||||
|
<h3>Clear All Surveys?</h3>
|
||||||
|
<p>Are you sure you want to delete all surveys? This action cannot be undone.</p>
|
||||||
|
<div class="modal-actions">
|
||||||
|
<button class="btn btn-secondary" id="btn-cancel-clear-all">Cancel</button>
|
||||||
|
<button class="btn btn-danger" id="btn-confirm-clear-all">Clear All</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Toast Notification -->
|
||||||
|
<div class="toast" id="toast" style="display: none;">
|
||||||
|
<span id="toast-message"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/static/app.js?v=5"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user