all repos — go-lift @ main

Lightweight workout tracker prototype..

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 }}