rynfkn commited on
Commit
7e32569
·
1 Parent(s): 6452d3b

add website template

Browse files
Files changed (3) hide show
  1. static/css/styles.css +116 -0
  2. static/js/main.js +68 -0
  3. templates/index.html +263 -0
static/css/styles.css ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --primary-color: #4a90e2;
3
+ --secondary-color: #6f42c1;
4
+ --light-bg: #f8f9fa;
5
+ --border-radius: 10px;
6
+ }
7
+
8
+ body {
9
+ background-color: var(--light-bg);
10
+ padding: 20px 0;
11
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
12
+ }
13
+
14
+ .card {
15
+ border-radius: var(--border-radius);
16
+ box-shadow: 0 5px 15px rgba(0,0,0,0.1);
17
+ overflow: hidden;
18
+ margin-bottom: 30px;
19
+ }
20
+
21
+ .header {
22
+ padding: 25px 20px;
23
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
24
+ color: white;
25
+ }
26
+
27
+ .card-body {
28
+ padding: 25px;
29
+ }
30
+
31
+ .form-label {
32
+ font-weight: 600;
33
+ color: #495057;
34
+ margin-bottom: 4px;
35
+ }
36
+
37
+ .form-control, .form-select {
38
+ border-radius: 8px;
39
+ padding: 8px 12px;
40
+ border: 1px solid #ced4da;
41
+ }
42
+
43
+ .feature-group {
44
+ background-color: rgba(248, 249, 250, 0.7);
45
+ border-radius: var(--border-radius);
46
+ padding: 15px;
47
+ margin-bottom: 15px;
48
+ border: 1px solid #e9ecef;
49
+ }
50
+
51
+ .feature-group h5 {
52
+ font-size: 1rem;
53
+ color: var(--secondary-color);
54
+ margin-bottom: 12px;
55
+ border-bottom: 1px solid #e9ecef;
56
+ padding-bottom: 8px;
57
+ }
58
+
59
+ .section-title {
60
+ color: #495057;
61
+ border-bottom: 2px solid var(--secondary-color);
62
+ padding-bottom: 8px;
63
+ margin-bottom: 15px;
64
+ font-size: 1.25rem;
65
+ }
66
+
67
+ .btn-primary {
68
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
69
+ border: none;
70
+ border-radius: 8px;
71
+ padding: 10px 25px;
72
+ font-weight: 600;
73
+ transition: all 0.3s;
74
+ }
75
+
76
+ .btn-primary:hover {
77
+ transform: translateY(-2px);
78
+ box-shadow: 0 5px 15px rgba(0,0,0,0.2);
79
+ }
80
+
81
+ .result-box, .error-box {
82
+ background-color: var(--light-bg);
83
+ border-radius: var(--border-radius);
84
+ padding: 20px;
85
+ margin-top: 20px;
86
+ text-align: center;
87
+ display: none;
88
+ }
89
+
90
+ .result-box {
91
+ border-left: 5px solid #28a745;
92
+ }
93
+
94
+ .error-box {
95
+ border-left: 5px solid #dc3545;
96
+ }
97
+
98
+ .progress {
99
+ height: 8px;
100
+ margin: 20px 0;
101
+ display: none;
102
+ }
103
+
104
+ #imagePreview {
105
+ max-width: 100%;
106
+ max-height: 180px;
107
+ border-radius: var(--border-radius);
108
+ display: none;
109
+ margin-top: 10px;
110
+ border: 1px solid #e9ecef;
111
+ }
112
+
113
+ footer {
114
+ color: #6c757d;
115
+ font-size: 14px;
116
+ }
static/js/main.js ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $(document).ready(function() {
2
+ // Image preview
3
+ $('#image').change(function() {
4
+ const file = this.files[0];
5
+ if (file) {
6
+ const reader = new FileReader();
7
+ reader.onload = function(e) {
8
+ $('#imagePreview').attr('src', e.target.result).show();
9
+ }
10
+ reader.readAsDataURL(file);
11
+ }
12
+ });
13
+
14
+ // City change handler - can be used to filter housing options
15
+ $('#City').change(function() {
16
+ const cityId = $(this).val();
17
+ const housingSelect = $('#Nama_Perumahan');
18
+
19
+ // Disable select while filtering (can be expanded with actual filtering logic)
20
+ housingSelect.prop('disabled', true);
21
+ setTimeout(() => {
22
+ housingSelect.prop('disabled', false);
23
+ }, 300);
24
+ });
25
+
26
+ // Form submission with your provided API call
27
+ $('#predictionForm').submit(function(e) {
28
+ e.preventDefault();
29
+
30
+ // Hide previous results and show progress
31
+ $('#resultBox').hide();
32
+ $('#errorBox').hide();
33
+ $('.progress').show();
34
+
35
+ // Create form data
36
+ const formData = new FormData(this);
37
+
38
+ // Make AJAX request
39
+ $.ajax({
40
+ url: '/predict',
41
+ type: 'POST',
42
+ data: formData,
43
+ contentType: false,
44
+ processData: false,
45
+ success: function(response) {
46
+ console.log("Success response:", response);
47
+ $('.progress').hide();
48
+
49
+ let price;
50
+ if (Array.isArray(response.predicted_price_millions)) {
51
+ price = response.predicted_price_millions[0];
52
+ } else {
53
+ price = response.predicted_price_millions;
54
+ }
55
+
56
+ $('#prediction').text('IDR ' + response.predicted_price_millions[0]);
57
+
58
+ $('#resultBox').show();
59
+ },
60
+ error: function(xhr) {
61
+ $('.progress').hide();
62
+ const errorData = JSON.parse(xhr.responseText);
63
+ $('#errorMessage').text(errorData.error);
64
+ $('#errorBox').show();
65
+ }
66
+ });
67
+ });
68
+ });
templates/index.html ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Property Price Predictor</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
8
+ <link rel="stylesheet" href="/static/css/styles.css">
9
+ </head>
10
+ <body>
11
+ <div class="container">
12
+ <div class="card">
13
+ <div class="header text-center">
14
+ <h1 class="display-5">Property Price Predictor</h1>
15
+ </div>
16
+
17
+ <div class="card-body">
18
+ <form id="predictionForm" enctype="multipart/form-data">
19
+ <div class="row">
20
+ <!-- Left -->
21
+ <div class="col-md-6">
22
+ <h4 class="section-title">Property Overview</h4>
23
+
24
+ <div class="mb-3">
25
+ <label for="title" class="form-label">Property Title/Description</label>
26
+ <textarea class="form-control" id="title" name="title" rows="2" required placeholder="Describe the property (e.g., '3BR Modern Villa in Surabaya')"></textarea>
27
+ </div>
28
+
29
+ <div class="mb-3">
30
+ <label for="image" class="form-label">Property Image</label>
31
+ <input type="file" class="form-control" id="image" name="image" accept="image/*" required>
32
+ <img id="imagePreview" src="#" alt="Property image preview">
33
+ </div>
34
+
35
+ <div class="feature-group">
36
+ <h5>Location</h5>
37
+ <div class="row">
38
+ <div class="col-md-6 mb-3">
39
+ <label for="City" class="form-label">City</label>
40
+ <select class="form-select" id="City" name="City" required>
41
+ <option value="" disabled selected>Select City</option>
42
+ <option value="0">Malang</option>
43
+ <option value="1">Sidoarjo</option>
44
+ <option value="2">Surabaya</option>
45
+ </select>
46
+ </div>
47
+ <div class="col-md-6 mb-3">
48
+ <label for="District" class="form-label">District</label>
49
+ <select class="form-select" id="District" name="District" required>
50
+ <option value="" disabled selected>Select District</option>
51
+ <!-- All district options -->
52
+ <option value="0">Blimbing</option>
53
+ <option value="1">Dau</option>
54
+ <option value="2">Dinoyo</option>
55
+ <option value="3">Dukuh Pakis</option>
56
+ <option value="4">Gedangan</option>
57
+ <option value="5">Griya Shanta</option>
58
+ <option value="6">Gubeng</option>
59
+ <option value="7">Jatimulyo</option>
60
+ <option value="8">Kedungkandang</option>
61
+ <option value="9">Kenjeran</option>
62
+ <option value="10">Lowokwaru</option>
63
+ <option value="11">Malang Kota</option>
64
+ <option value="12">Merjosari</option>
65
+ <option value="13">Mojolangu</option>
66
+ <option value="14">Mulyorejo</option>
67
+ <option value="15">Pakis</option>
68
+ <option value="16">Pakuwon City</option>
69
+ <option value="17">Pakuwon Indah</option>
70
+ <option value="18">Permata Jingga</option>
71
+ <option value="19">Rungkut</option>
72
+ <option value="20">Sidoarjo</option>
73
+ <option value="21">Soekarno Hatta</option>
74
+ <option value="22">Sukolilo</option>
75
+ <option value="23">Sukun</option>
76
+ <option value="24">Surabaya Kota</option>
77
+ <option value="25">Tenggilis Mejoyo</option>
78
+ <option value="26">Tlogomas</option>
79
+ <option value="27">Wagir</option>
80
+ <option value="28">Waru</option>
81
+ </select>
82
+ </div>
83
+ </div>
84
+
85
+ <div class="row">
86
+ <div class="col-md-6 mb-3">
87
+ <label for="Latitude" class="form-label">Latitude</label>
88
+ <input type="number" step="any" class="form-control" id="Latitude" name="Latitude" placeholder="e.g., -7.2575" required>
89
+ </div>
90
+ <div class="col-md-6 mb-3">
91
+ <label for="Longitude" class="form-label">Longitude</label>
92
+ <input type="number" step="any" class="form-control" id="Longitude" name="Longitude" placeholder="e.g., 112.7521" required>
93
+ </div>
94
+ </div>
95
+ </div>
96
+
97
+ <div class="feature-group">
98
+ <h5>Property Size</h5>
99
+ <div class="row">
100
+ <div class="col-md-6 mb-3">
101
+ <label for="Luas_Tanah" class="form-label">Luas Tanah (m²)</label>
102
+ <input type="number" min="0" step="any" class="form-control" id="Luas_Tanah" name="Luas Tanah" required>
103
+ </div>
104
+ <div class="col-md-6 mb-3">
105
+ <label for="Luas_Bangunan" class="form-label">Luas Bangunan (m²)</label>
106
+ <input type="number" min="0" step="any" class="form-control" id="Luas_Bangunan" name="Luas Bangunan" required>
107
+ </div>
108
+ </div>
109
+ </div>
110
+
111
+ <div class="feature-group">
112
+ <h5>Basic Features</h5>
113
+ <div class="row">
114
+ <div class="col-md-6 mb-3">
115
+ <label for="Kamar_Tidur" class="form-label">Kamar Tidur</label>
116
+ <input type="number" min="0" class="form-control" id="Kamar_Tidur" name="Kamar Tidur" required>
117
+ </div>
118
+ <div class="col-md-6 mb-3">
119
+ <label for="Kamar_Mandi" class="form-label">Kamar Mandi</label>
120
+ <input type="number" min="0" class="form-control" id="Kamar_Mandi" name="Kamar Mandi" required>
121
+ </div>
122
+ </div>
123
+
124
+ <div class="row">
125
+ <div class="col-md-6 mb-3">
126
+ <label for="Jumlah_Lantai" class="form-label">Jumlah Lantai</label>
127
+ <input type="number" min="1" class="form-control" id="Jumlah_Lantai" name="Jumlah Lantai" required>
128
+ </div>
129
+ <div class="col-md-6 mb-3">
130
+ <label for="Tahun_Dibangun" class="form-label">Tahun Dibangun</label>
131
+ <input type="number" min="1900" max="2025" class="form-control" id="Tahun_Dibangun" name="Tahun Dibangun" placeholder="e.g., 2010" required>
132
+ </div>
133
+ </div>
134
+ </div>
135
+ </div>
136
+
137
+ <!-- Right -->
138
+ <div class="col-md-6">
139
+ <h4 class="section-title">Property Details</h4>
140
+
141
+ <div class="feature-group">
142
+ <h5>Housing Complex</h5>
143
+ <div class="mb-3">
144
+ <label for="Nama_Perumahan" class="form-label">Nama Perumahan</label>
145
+ <select class="form-select" id="Nama_Perumahan" name="Nama Perumahan" required>
146
+ <option value="" disabled selected>Select Housing Complex</option>
147
+ <option value="0">-</option>
148
+ <option value="1">Alana Regency Cemandi</option>
149
+ <option value="2">Amesta living</option>
150
+ <option value="3">Anggrek Residence</option>
151
+ <option value="4">Atrani Residence</option>
152
+ <option value="5">Babatan Pantai</option>
153
+ <option value="6">Barata Jaya</option>
154
+ <option value="7">Baruk Utara</option>
155
+ <option value="8">Bratang Binangun</option>
156
+ <option value="9">Citra Garden</option>
157
+ <option value="10">Citra Garden Sidoarjo</option>
158
+ <option value="11">Citra Harmoni</option>
159
+ <option value="12">Citra garden</option>
160
+ <option value="13">D'gardenia City</option>
161
+ <option value="14">DE IMPERIAL ESTATE</option>
162
+ <option value="15">Darmo Permai</option>
163
+ <option value="72">Pakuwon City</option>
164
+ <option value="112">Puri Surya Jaya</option>
165
+ <option value="115">Rungkut Asri</option>
166
+ <option value="118">Rungkut Mapan</option>
167
+ <option value="119">Rungkut Menanggal</option>
168
+ <option value="128">Sutorejo Prima</option>
169
+ <option value="140">Unknown</option>
170
+ <option value="158">Sukolilo Dian Regency</option>
171
+ </select>
172
+ </div>
173
+ </div>
174
+
175
+ <div class="feature-group">
176
+ <h5>Parking & Electricity</h5>
177
+ <div class="row">
178
+ <div class="col-md-6 mb-3">
179
+ <label for="Carpots" class="form-label">Carports</label>
180
+ <input type="number" min="0" class="form-control" id="Carpots" name="Carpots" required>
181
+ </div>
182
+ <div class="col-md-6 mb-3">
183
+ <label for="Garasi" class="form-label">Garasi</label>
184
+ <input type="number" min="0" class="form-control" id="Garasi" name="Garasi" required>
185
+ </div>
186
+ </div>
187
+ <div class="mb-3">
188
+ <label for="Daya_Listrik" class="form-label">Daya Listrik (Watt)</label>
189
+ <input type="number" min="0" step="100" class="form-control" id="Daya_Listrik" name="Daya Listrik" placeholder="e.g., 2200" required>
190
+ </div>
191
+ </div>
192
+
193
+ <div class="feature-group">
194
+ <h5>Property Specifications</h5>
195
+ <div class="row">
196
+ <div class="col-md-6 mb-3">
197
+ <label for="Sertifikat" class="form-label">Sertifikat</label>
198
+ <select class="form-select" id="Sertifikat" name="Sertifikat" required>
199
+ <option value="" disabled selected>Select Certificate Type</option>
200
+ <option value="0">HGB</option>
201
+ <option value="1">Hak Pakai</option>
202
+ <option value="2">Lain-lain</option>
203
+ <option value="3">SHM</option>
204
+ <option value="4">Strata Title</option>
205
+ </select>
206
+ </div>
207
+ <div class="col-md-6 mb-3">
208
+ <label for="Interior" class="form-label">Interior</label>
209
+ <select class="form-select" id="Interior" name="Interior" required>
210
+ <option value="" disabled selected>Select Interior Type</option>
211
+ <option value="0">Full Furnished</option>
212
+ <option value="1">Semi Furnished</option>
213
+ <option value="2">Unfurnished</option>
214
+ <option value="3">Unknown</option>
215
+ </select>
216
+ </div>
217
+ </div>
218
+ <div class="mb-3">
219
+ <label for="Orientasi_Bangunan" class="form-label">Orientasi Bangunan</label>
220
+ <select class="form-select" id="Orientasi_Bangunan" name="Orientasi Bangunan" required>
221
+ <option value="" disabled selected>Select Building Orientation</option>
222
+ <option value="0">Barat</option>
223
+ <option value="1">Barat Daya</option>
224
+ <option value="2">Barat Laut</option>
225
+ <option value="3">Hook</option>
226
+ <option value="4">Selatan</option>
227
+ <option value="5">Timur</option>
228
+ <option value="6">Timur Laut</option>
229
+ <option value="7">Unknown</option>
230
+ <option value="8">Utara</option>
231
+ </select>
232
+ </div>
233
+ </div>
234
+
235
+ <div class="text-center mt-4">
236
+ <button type="submit" class="btn btn-primary btn-lg px-5">Predict Property Price</button>
237
+ </div>
238
+
239
+ <div class="progress">
240
+ <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 100%"></div>
241
+ </div>
242
+
243
+ <div id="resultBox" class="result-box">
244
+ <h4>Estimated Property Price</h4>
245
+ <h2 id="prediction" class="text-success"></h2>
246
+ <p class="text-muted">This is an AI-generated estimate based on the provided information.</p>
247
+ </div>
248
+
249
+ <div id="errorBox" class="error-box">
250
+ <h4>Error</h4>
251
+ <p id="errorMessage"></p>
252
+ </div>
253
+ </div>
254
+ </div>
255
+ </form>
256
+ </div>
257
+ </div>
258
+ </div>
259
+
260
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
261
+ <script src="/static/js/main.js"></script>
262
+ </body>
263
+ </html>