templates/profile.gohtml (view raw)
1{{ define "body" }}
2<h1>Go Lift</h1>
3<div class="profile-container">
4 <h2>User Profile</h2>
5
6 <div class="button-group">
7 <button id="editBtn" onclick="toggleEditMode(true)">Edit</button>
8 <button id="saveBtn" onclick="saveProfile()" style="display:none">Save</button>
9 <button id="cancelBtn" onclick="toggleEditMode(false)" style="display:none">Cancel</button>
10 </div>
11
12 <form id="profileForm">
13 <div class="form-group">
14 <label for="name">Name:</label>
15 <input type="text" id="name" name="name" value="" disabled>
16 </div>
17
18 <div class="form-group">
19 <label>Gender:</label>
20 <div class="radio-group">
21 <input type="radio" id="male" name="isFemale" value="false" disabled>
22 <label for="male">Male</label>
23 <input type="radio" id="female" name="isFemale" value="true" disabled>
24 <label for="female">Female</label>
25 </div>
26 </div>
27
28 <div class="form-group">
29 <label for="height">Height (cm):</label>
30 <input type="number" id="height" name="height" value="" step="0.1" disabled>
31 </div>
32
33 <div class="form-group">
34 <label for="weight">Weight (kg):</label>
35 <input type="number" id="weight" name="weight" value="" step="0.1" disabled>
36 </div>
37
38 <div class="form-group">
39 <label for="birthDate">Birth Date:</label>
40 <input type="date" id="birthDate" name="birthDate" value="" disabled>
41 </div>
42 </form>
43</div>
44
45<script>
46 // Store original values for cancel functionality
47 let originalValues = {};
48
49 // Fetch user profile data from API
50 function fetchProfileData() {
51 fetch('/api/users/1')
52 .then(response => {
53 if (!response.ok) {
54 throw new Error('Failed to fetch profile data');
55 }
56 return response.json();
57 })
58 .then(data => {
59 populateFormData(data);
60 saveOriginalValues();
61 })
62 .catch(error => {
63 console.error('Error:', error);
64 alert('Failed to load profile: ' + error.message);
65 });
66 }
67
68 // Populate form with profile data
69 function populateFormData(userData) {
70 document.getElementById('name').value = userData.name || '';
71 document.getElementById('height').value = userData.height || '';
72 document.getElementById('weight').value = userData.weight || '';
73
74 if (userData.birthDate) {
75 document.getElementById('birthDate').value = userData.birthDate.split('T')[0];
76 }
77
78 // Set gender radio button
79 if (userData.isFemale !== undefined) {
80 document.getElementById('female').checked = userData.isFemale;
81 document.getElementById('male').checked = !userData.isFemale;
82 }
83 }
84
85 // Capture initial values
86 function saveOriginalValues() {
87 const form = document.getElementById('profileForm');
88 const formElements = form.elements;
89
90 for (let i = 0; i < formElements.length; i++) {
91 const element = formElements[i];
92 if (element.name) {
93 if (element.type === 'radio') {
94 if (element.checked) {
95 originalValues[element.name] = element.value;
96 }
97 } else {
98 originalValues[element.name] = element.value;
99 }
100 }
101 }
102 }
103
104 // Toggle between view and edit modes
105 function toggleEditMode(isEdit) {
106 const form = document.getElementById('profileForm');
107 const formElements = form.elements;
108
109 // If entering edit mode, save original values
110 if (isEdit) {
111 saveOriginalValues();
112 }
113
114 // Toggle form field disabled state
115 for (let i = 0; i < formElements.length; i++) {
116 formElements[i].disabled = !isEdit;
117 }
118
119 // Toggle button visibility
120 document.getElementById('editBtn').style.display = isEdit ? 'none' : 'inline-block';
121 document.getElementById('saveBtn').style.display = isEdit ? 'inline-block' : 'none';
122 document.getElementById('cancelBtn').style.display = isEdit ? 'inline-block' : 'none';
123
124 // If canceling, restore original values
125 if (!isEdit) {
126 restoreOriginalValues();
127 }
128 }
129
130 // Restore original form values
131 function restoreOriginalValues() {
132 const form = document.getElementById('profileForm');
133
134 for (const name in originalValues) {
135 const elements = form.elements[name];
136
137 if (elements.length > 1) {
138 // Handle radio buttons
139 for (let i = 0; i < elements.length; i++) {
140 elements[i].checked = elements[i].value === originalValues[name];
141 }
142 } else {
143 elements.value = originalValues[name];
144 }
145 }
146 }
147
148 // Save profile changes
149 function saveProfile() {
150 const form = document.getElementById('profileForm');
151 const formData = new FormData(form);
152 const userData = {};
153
154 // Convert form data to JSON
155 for (const [key, value] of formData.entries()) {
156 if (key === 'isFemale') {
157 userData[key] = value === 'true';
158 } else if (key === 'height' || key === 'weight') {
159 userData[key] = value ? parseFloat(value) : null;
160 } else if (key === 'birthDate') {
161 userData[key] = value ? new Date(value).toISOString() : null;
162 } else {
163 userData[key] = value || null;
164 }
165 }
166
167 // Send PUT request
168 fetch('/api/users/1', {
169 method: 'PUT',
170 headers: {
171 'Content-Type': 'application/json',
172 },
173 body: JSON.stringify(userData)
174 })
175 .then(response => {
176 if (!response.ok) {
177 throw new Error('Failed to update profile');
178 }
179 return response.json();
180 })
181 .then(data => {
182 toggleEditMode(false);
183 // Refresh data
184 fetchProfileData();
185 })
186 .catch(error => {
187 console.error('Error:', error);
188 alert('Failed to update profile: ' + error.message);
189 });
190 }
191
192 // Initialize when page loads
193 document.addEventListener('DOMContentLoaded', function() {
194 fetchProfileData();
195 });
196</script>
197
198<style>
199 .profile-container {
200 max-width: 600px;
201 margin: 0 auto;
202 padding: 20px;
203 }
204
205 .form-group {
206 margin-bottom: 15px;
207 }
208
209 .form-group label {
210 display: block;
211 margin-bottom: 5px;
212 font-weight: bold;
213 }
214
215 .form-group input {
216 width: 100%;
217 padding: 8px;
218 border: 1px solid #ddd;
219 border-radius: 4px;
220 }
221
222 .radio-group {
223 display: flex;
224 gap: 15px;
225 }
226
227 .radio-group input {
228 width: auto;
229 }
230
231 .button-group {
232 margin-bottom: 20px;
233 }
234
235 button {
236 padding: 8px 16px;
237 margin-right: 10px;
238 cursor: pointer;
239 }
240</style>
241{{ end }}