Spaces:
Sleeping
Sleeping
cg calculator added
Browse files- database.db +0 -0
- main.py +13 -0
- static/app.js +10 -1
- static/cg.js +82 -0
- static/styles.css +83 -6
- templates/cg.html +60 -0
- templates/index.html +52 -40
database.db
CHANGED
Binary files a/database.db and b/database.db differ
|
|
main.py
CHANGED
@@ -84,3 +84,16 @@ async def delete_cable(cable_id: int, db: Session = Depends(get_db)):
|
|
84 |
db.delete(cable)
|
85 |
db.commit()
|
86 |
return RedirectResponse(url="/edit_cables", status_code=303)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
db.delete(cable)
|
85 |
db.commit()
|
86 |
return RedirectResponse(url="/edit_cables", status_code=303)
|
87 |
+
|
88 |
+
|
89 |
+
@app.get("/cg", response_class=HTMLResponse)
|
90 |
+
async def cg_page(request: Request, db: Session = Depends(get_db)):
|
91 |
+
cables = db.query(Cable).all()
|
92 |
+
return templates.TemplateResponse("cg.html", {"request": request, "cables": cables})
|
93 |
+
|
94 |
+
@app.get("/get_resistance/{awg}", response_model=dict)
|
95 |
+
async def get_resistance(awg: str, db: Session = Depends(get_db)):
|
96 |
+
cable = db.query(Cable).filter(Cable.type == awg).first()
|
97 |
+
if not cable:
|
98 |
+
raise HTTPException(status_code=404, detail="Cable type not found")
|
99 |
+
return {"resistance": cable.resistance}
|
static/app.js
CHANGED
@@ -1,8 +1,10 @@
|
|
1 |
document.addEventListener('DOMContentLoaded', function() {
|
|
|
2 |
const form = document.getElementById('calculator-form');
|
3 |
const cableContainer = document.getElementById('cable-container');
|
4 |
const addCableButton = document.getElementById('add-cable');
|
5 |
const calculateButton = document.querySelector('.btn-calculate');
|
|
|
6 |
let cableCount = 1;
|
7 |
const maxCables = 3;
|
8 |
|
@@ -88,7 +90,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
88 |
}
|
89 |
});
|
90 |
|
91 |
-
// Handle form submission
|
92 |
form.addEventListener('submit', async function(event) {
|
93 |
event.preventDefault();
|
94 |
|
@@ -130,6 +132,13 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
130 |
}
|
131 |
});
|
132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
// Initially check the form validity and update buttons on page load
|
134 |
form.addEventListener('input', checkFormValidity);
|
135 |
checkFormValidity();
|
|
|
1 |
document.addEventListener('DOMContentLoaded', function() {
|
2 |
+
// Voltage Drop Calculator Elements
|
3 |
const form = document.getElementById('calculator-form');
|
4 |
const cableContainer = document.getElementById('cable-container');
|
5 |
const addCableButton = document.getElementById('add-cable');
|
6 |
const calculateButton = document.querySelector('.btn-calculate');
|
7 |
+
|
8 |
let cableCount = 1;
|
9 |
const maxCables = 3;
|
10 |
|
|
|
90 |
}
|
91 |
});
|
92 |
|
93 |
+
// Handle form submission for voltage drop calculator
|
94 |
form.addEventListener('submit', async function(event) {
|
95 |
event.preventDefault();
|
96 |
|
|
|
132 |
}
|
133 |
});
|
134 |
|
135 |
+
|
136 |
+
|
137 |
+
// Helper function to calculate voltage drop
|
138 |
+
function calculateVoltageDrop(voltage, current, length, resistance) {
|
139 |
+
return current * length * resistance;
|
140 |
+
}
|
141 |
+
|
142 |
// Initially check the form validity and update buttons on page load
|
143 |
form.addEventListener('input', checkFormValidity);
|
144 |
checkFormValidity();
|
static/cg.js
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
document.addEventListener('DOMContentLoaded', function() {
|
2 |
+
// Handle form submission for Crystal Grid calculator
|
3 |
+
const cgForm = document.getElementById('cg-calculator-form');
|
4 |
+
const cgCalculateButton = document.querySelector('.btn-cg-calculate'); // Select the calculate button
|
5 |
+
|
6 |
+
if (cgForm && cgCalculateButton) {
|
7 |
+
// Check form validity and toggle the calculate button state
|
8 |
+
function checkFormValidity() {
|
9 |
+
const isValid = cgForm.checkValidity();
|
10 |
+
if (isValid) {
|
11 |
+
cgCalculateButton.disabled = false;
|
12 |
+
cgCalculateButton.classList.add('enabled');
|
13 |
+
} else {
|
14 |
+
cgCalculateButton.disabled = true;
|
15 |
+
cgCalculateButton.classList.remove('enabled');
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
// Initial check on page load
|
20 |
+
checkFormValidity();
|
21 |
+
|
22 |
+
// Add event listener to check form validity on input change
|
23 |
+
cgForm.addEventListener('input', checkFormValidity);
|
24 |
+
|
25 |
+
// Handle form submission
|
26 |
+
cgForm.addEventListener('submit', async function(event) {
|
27 |
+
event.preventDefault(); // Prevent the default form submission
|
28 |
+
|
29 |
+
const formData = new FormData(cgForm);
|
30 |
+
const voltage = parseFloat(formData.get('voltage')) || null;
|
31 |
+
const cableLength = parseFloat(formData.get('cable_length')) || null;
|
32 |
+
const awg = formData.get('awg') || null;
|
33 |
+
const fixtureHeight = parseFloat(formData.get('fixture_height')) || null;
|
34 |
+
const levels = parseInt(formData.get('levels')) || null;
|
35 |
+
const ledsPerLevel = parseInt(formData.get('leds_per_level')) || 6;
|
36 |
+
const ledPower = parseFloat(formData.get('led_power')) || null;
|
37 |
+
|
38 |
+
const totalLEDs = levels && ledsPerLevel ? levels * ledsPerLevel : null;
|
39 |
+
const levelHeight = fixtureHeight && levels ? fixtureHeight / levels : null;
|
40 |
+
|
41 |
+
if (awg && voltage && cableLength) {
|
42 |
+
try {
|
43 |
+
const response = await fetch(`/get_resistance/${awg}`);
|
44 |
+
if (response.ok) {
|
45 |
+
const { resistance } = await response.json();
|
46 |
+
|
47 |
+
let resultsHtml = '';
|
48 |
+
if (totalLEDs !== null && levelHeight !== null && ledPower !== null) {
|
49 |
+
const totalPower = totalLEDs * ledPower;
|
50 |
+
const current = totalPower / voltage;
|
51 |
+
let remainingVoltage = voltage;
|
52 |
+
|
53 |
+
resultsHtml += `<p>Total LEDs: ${totalLEDs}</p>`;
|
54 |
+
for (let i = 1; i <= levels; i++) {
|
55 |
+
const length = i * levelHeight + cableLength;
|
56 |
+
const voltageDrop = calculateVoltageDrop(current, length, resistance);
|
57 |
+
remainingVoltage -= voltageDrop;
|
58 |
+
resultsHtml += `<p>Level ${i}: Final Voltage: ${remainingVoltage.toFixed(2)} V</p>`;
|
59 |
+
}
|
60 |
+
} else {
|
61 |
+
resultsHtml = `<p>Partial data provided. Calculation incomplete.</p>`;
|
62 |
+
}
|
63 |
+
document.getElementById('result').innerHTML = resultsHtml;
|
64 |
+
} else {
|
65 |
+
console.error("Error fetching resistance:", response.statusText);
|
66 |
+
document.getElementById('result').innerHTML = `<p>Error: Unable to fetch cable resistance.</p>`;
|
67 |
+
}
|
68 |
+
} catch (error) {
|
69 |
+
console.error("An error occurred:", error);
|
70 |
+
document.getElementById('result').innerHTML = `<p>Error: An unexpected error occurred.</p>`;
|
71 |
+
}
|
72 |
+
} else {
|
73 |
+
document.getElementById('result').innerHTML = `<p>Please provide at least Voltage, Cable Length, and AWG to perform calculations.</p>`;
|
74 |
+
}
|
75 |
+
});
|
76 |
+
}
|
77 |
+
|
78 |
+
// Function to calculate voltage drop
|
79 |
+
function calculateVoltageDrop(current, length, resistance) {
|
80 |
+
return current * length * resistance;
|
81 |
+
}
|
82 |
+
});
|
static/styles.css
CHANGED
@@ -4,6 +4,9 @@ body {
|
|
4 |
background-color: #f8f9fa;
|
5 |
margin: 0;
|
6 |
padding: 0;
|
|
|
|
|
|
|
7 |
}
|
8 |
|
9 |
header {
|
@@ -25,14 +28,38 @@ h1 {
|
|
25 |
margin: 0;
|
26 |
}
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
.calculator-main {
|
|
|
29 |
display: flex;
|
30 |
flex-direction: column;
|
31 |
align-items: center;
|
32 |
-
|
33 |
-
width: 100%;
|
34 |
-
max-width: 1200px;
|
35 |
padding: 20px;
|
|
|
|
|
36 |
box-sizing: border-box;
|
37 |
}
|
38 |
|
@@ -141,6 +168,17 @@ h1 {
|
|
141 |
cursor: pointer;
|
142 |
}
|
143 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
.btn-remove-cable {
|
145 |
background-color: #dc3545;
|
146 |
padding: 3px 8px;
|
@@ -150,6 +188,28 @@ h1 {
|
|
150 |
right: 10px;
|
151 |
}
|
152 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
.action-buttons {
|
154 |
display: flex;
|
155 |
justify-content: center;
|
@@ -175,10 +235,17 @@ h1 {
|
|
175 |
background-color: #007bff;
|
176 |
color: white;
|
177 |
padding: 8px 16px;
|
178 |
-
font-size:
|
179 |
text-align: center;
|
|
|
|
|
|
|
|
|
|
|
180 |
text-decoration: none;
|
181 |
-
|
|
|
|
|
182 |
}
|
183 |
|
184 |
.btn-back:hover {
|
@@ -197,6 +264,16 @@ h1 {
|
|
197 |
}
|
198 |
|
199 |
@media (max-width: 768px) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
#cable-container .cable-group {
|
201 |
flex: 1 1 100%; /* Full width for all cables on small screens */
|
202 |
}
|
@@ -243,4 +320,4 @@ h1 {
|
|
243 |
.add-cable-section h2, .existing-cables-section h2 {
|
244 |
margin-bottom: 20px;
|
245 |
color: #343a40;
|
246 |
-
}
|
|
|
4 |
background-color: #f8f9fa;
|
5 |
margin: 0;
|
6 |
padding: 0;
|
7 |
+
display: flex;
|
8 |
+
flex-direction: column;
|
9 |
+
align-items: center;
|
10 |
}
|
11 |
|
12 |
header {
|
|
|
28 |
margin: 0;
|
29 |
}
|
30 |
|
31 |
+
.content-wrapper {
|
32 |
+
display: flex;
|
33 |
+
width: 100%;
|
34 |
+
max-width: 1200px;
|
35 |
+
margin-top: 30px;
|
36 |
+
padding: 0 20px;
|
37 |
+
box-sizing: border-box;
|
38 |
+
}
|
39 |
+
|
40 |
+
.nav-section {
|
41 |
+
flex: 0 0 200px; /* Fixed width for the navigation */
|
42 |
+
margin-right: 20px;
|
43 |
+
padding: 20px;
|
44 |
+
background-color: #fff;
|
45 |
+
border-radius: 8px;
|
46 |
+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
47 |
+
box-sizing: border-box;
|
48 |
+
display: flex;
|
49 |
+
flex-direction: column;
|
50 |
+
gap: 10px; /* Spacing between buttons */
|
51 |
+
}
|
52 |
+
|
53 |
+
|
54 |
.calculator-main {
|
55 |
+
flex: 1;
|
56 |
display: flex;
|
57 |
flex-direction: column;
|
58 |
align-items: center;
|
59 |
+
background-color: white;
|
|
|
|
|
60 |
padding: 20px;
|
61 |
+
border-radius: 8px;
|
62 |
+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
63 |
box-sizing: border-box;
|
64 |
}
|
65 |
|
|
|
168 |
cursor: pointer;
|
169 |
}
|
170 |
|
171 |
+
|
172 |
+
.btn-cg-calculate {
|
173 |
+
background-color: #6c757d; /* Disabled state */
|
174 |
+
cursor: not-allowed;
|
175 |
+
}
|
176 |
+
|
177 |
+
.btn-cg-calculate.enabled {
|
178 |
+
background-color: #28a745; /* Enabled state */
|
179 |
+
cursor: pointer;
|
180 |
+
}
|
181 |
+
|
182 |
.btn-remove-cable {
|
183 |
background-color: #dc3545;
|
184 |
padding: 3px 8px;
|
|
|
188 |
right: 10px;
|
189 |
}
|
190 |
|
191 |
+
.btn-nav {
|
192 |
+
background-color: #007bff;
|
193 |
+
color: white;
|
194 |
+
padding: 10px 16px;
|
195 |
+
font-size: 14px;
|
196 |
+
text-align: center;
|
197 |
+
border-radius: 4px;
|
198 |
+
transition: background-color 0.3s ease;
|
199 |
+
cursor: pointer;
|
200 |
+
border: none; /* Remove default button border */
|
201 |
+
display: block;
|
202 |
+
width: 100%; /* Full width within the nav section */
|
203 |
+
text-align: center;
|
204 |
+
width: 150px;
|
205 |
+
margin-top: 20px;
|
206 |
+
}
|
207 |
+
|
208 |
+
.btn-nav:hover {
|
209 |
+
background-color: #0056b3;
|
210 |
+
}
|
211 |
+
|
212 |
+
|
213 |
.action-buttons {
|
214 |
display: flex;
|
215 |
justify-content: center;
|
|
|
235 |
background-color: #007bff;
|
236 |
color: white;
|
237 |
padding: 8px 16px;
|
238 |
+
font-size: 14px;
|
239 |
text-align: center;
|
240 |
+
border-radius: 4px;
|
241 |
+
transition: background-color 0.3s ease;
|
242 |
+
cursor: pointer;
|
243 |
+
border: none;
|
244 |
+
display: block;
|
245 |
text-decoration: none;
|
246 |
+
text-align: center;
|
247 |
+
width: 150px;
|
248 |
+
margin-top: 20px;
|
249 |
}
|
250 |
|
251 |
.btn-back:hover {
|
|
|
264 |
}
|
265 |
|
266 |
@media (max-width: 768px) {
|
267 |
+
.content-wrapper {
|
268 |
+
flex-direction: column;
|
269 |
+
align-items: center;
|
270 |
+
}
|
271 |
+
|
272 |
+
.nav-section {
|
273 |
+
flex: 0 0 100%;
|
274 |
+
margin-bottom: 20px;
|
275 |
+
}
|
276 |
+
|
277 |
#cable-container .cable-group {
|
278 |
flex: 1 1 100%; /* Full width for all cables on small screens */
|
279 |
}
|
|
|
320 |
.add-cable-section h2, .existing-cables-section h2 {
|
321 |
margin-bottom: 20px;
|
322 |
color: #343a40;
|
323 |
+
}
|
templates/cg.html
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!-- cg.html -->
|
2 |
+
<!DOCTYPE html>
|
3 |
+
<html lang="en">
|
4 |
+
<head>
|
5 |
+
<meta charset="UTF-8">
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
+
<title>Crystal Grid Calculator</title>
|
8 |
+
<link rel="stylesheet" href="/static/styles.css">
|
9 |
+
</head>
|
10 |
+
<body>
|
11 |
+
<header>
|
12 |
+
<h1>Crystal Grid Calculator</h1>
|
13 |
+
</header>
|
14 |
+
<main class="calculator-main">
|
15 |
+
<form id="cg-calculator-form">
|
16 |
+
<div class="form-row">
|
17 |
+
<label for="voltage">Voltage (V):</label>
|
18 |
+
<input type="number" id="voltage" name="voltage">
|
19 |
+
</div>
|
20 |
+
<div class="form-row">
|
21 |
+
<label for="cable_length">Input Cable Length (m):</label>
|
22 |
+
<input type="number" id="cable_length" name="cable_length">
|
23 |
+
</div>
|
24 |
+
<div class="form-row">
|
25 |
+
<label for="awg">Cable AWG:</label>
|
26 |
+
<select id="awg" name="awg">
|
27 |
+
{% for cable in cables %}
|
28 |
+
<option value="{{ cable.type }}">{{ cable.type }}</option>
|
29 |
+
{% endfor %}
|
30 |
+
</select>
|
31 |
+
</div>
|
32 |
+
<div class="form-row">
|
33 |
+
<label for="fixture_height">Fixture Height (m):</label>
|
34 |
+
<input type="number" id="fixture_height" name="fixture_height">
|
35 |
+
</div>
|
36 |
+
<div class="form-row">
|
37 |
+
<label for="levels">Number of Levels:</label>
|
38 |
+
<input type="number" id="levels" name="levels">
|
39 |
+
</div>
|
40 |
+
<div class="form-row">
|
41 |
+
<label for="leds_per_level">LEDs per Level:</label>
|
42 |
+
<input type="number" id="leds_per_level" name="leds_per_level" value="6">
|
43 |
+
</div>
|
44 |
+
<div class="form-row">
|
45 |
+
<label for="led_power">LED Power (W):</label>
|
46 |
+
<input type="number" id="led_power" name="led_power">
|
47 |
+
</div>
|
48 |
+
|
49 |
+
<div class="action-buttons">
|
50 |
+
<button type="submit" class="btn btn-cg-calculate">Calculate</button>
|
51 |
+
</div>
|
52 |
+
</form>
|
53 |
+
|
54 |
+
<div id="result" class="result-display"></div>
|
55 |
+
|
56 |
+
<a href="/" class="btn btn-back">Back to Calculator</a>
|
57 |
+
</main>
|
58 |
+
<script src="/static/cg.js"></script>
|
59 |
+
</body>
|
60 |
+
</html>
|
templates/index.html
CHANGED
@@ -11,54 +11,66 @@
|
|
11 |
<img src="/static/logo.png" alt="Company Logo" id="logo">
|
12 |
<h1>Voltage Drop Calculator</h1>
|
13 |
</header>
|
14 |
-
<
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
{% for cable in cables %}
|
24 |
-
<option value="{{ cable.type }}">{{ cable.type }}</option>
|
25 |
-
{% endfor %}
|
26 |
-
</select>
|
27 |
-
</div>
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
</div>
|
47 |
-
</div>
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
|
56 |
-
|
57 |
-
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
62 |
<script src="/static/app.js"></script>
|
63 |
</body>
|
64 |
</html>
|
|
|
11 |
<img src="/static/logo.png" alt="Company Logo" id="logo">
|
12 |
<h1>Voltage Drop Calculator</h1>
|
13 |
</header>
|
14 |
+
<div class="content-wrapper">
|
15 |
+
<nav class="nav-section">
|
16 |
+
<form action="/cg">
|
17 |
+
<button type="submit" class="btn btn-nav">Crystal Grid Calculator</button>
|
18 |
+
</form>
|
19 |
+
<form action="#">
|
20 |
+
<button type="submit" class="btn btn-nav">Crystal Pixel Calculator</button>
|
21 |
+
</form>
|
22 |
+
</nav>
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
+
<main class="calculator-main">
|
25 |
+
<!-- Form wraps all cable groups -->
|
26 |
+
<form id="calculator-form">
|
27 |
+
<div id="cable-container">
|
28 |
+
<div class="cable-group">
|
29 |
+
<h2>Cable 1</h2>
|
30 |
+
<div class="form-row">
|
31 |
+
<label for="cable_type-0">Cable Type:</label>
|
32 |
+
<select id="cable_type-0" name="cable_type[0]" required>
|
33 |
+
{% for cable in cables %}
|
34 |
+
<option value="{{ cable.type }}">{{ cable.type }}</option>
|
35 |
+
{% endfor %}
|
36 |
+
</select>
|
37 |
+
</div>
|
38 |
|
39 |
+
<div class="form-row">
|
40 |
+
<label for="voltage-0">Voltage:</label>
|
41 |
+
<input type="number" id="voltage-0" name="voltage[0]" required>
|
42 |
+
</div>
|
43 |
|
44 |
+
<div class="form-row">
|
45 |
+
<label for="load-0">Load (A):</label>
|
46 |
+
<input type="number" id="load-0" name="load[0]" required>
|
47 |
+
</div>
|
48 |
|
49 |
+
<div class="form-row">
|
50 |
+
<label for="length-0">Length (m):</label>
|
51 |
+
<input type="number" id="length-0" name="length[0]" required>
|
52 |
+
</div>
|
53 |
+
|
54 |
+
<!-- Remove Cable Button -->
|
55 |
+
<button type="button" class="btn btn-remove-cable" style="display: none;">- Remove Cable</button>
|
56 |
+
|
57 |
+
</div>
|
58 |
</div>
|
|
|
59 |
|
60 |
+
<!-- Action Buttons -->
|
61 |
+
<div class="action-buttons">
|
62 |
+
<button id="add-cable" type="button" class="btn btn-add-cable">+ Add Cable</button>
|
63 |
+
<button type="submit" class="btn btn-calculate">Calculate</button>
|
64 |
+
</div>
|
65 |
+
</form>
|
66 |
|
67 |
+
<!-- Results Display -->
|
68 |
+
<div id="result" class="result-display"></div>
|
69 |
|
70 |
+
<!-- Edit Cables Link -->
|
71 |
+
<a href="/edit_cables" class="btn btn-back">Edit Cables</a>
|
72 |
+
</main>
|
73 |
+
</div>
|
74 |
<script src="/static/app.js"></script>
|
75 |
</body>
|
76 |
</html>
|