Ignore:
Timestamp:
06/26/26 16:32:12 (2 days ago)
Author:
veronika-ils <ilioskaveronika@…>
Branches:
master
Parents:
fa32d0f
Message:

add functionality so that users can change passwords

File:
1 edited

Legend:

Unmodified
Added
Removed
  • petify-frontend/src/views/LoginView.vue

    rfa32d0f rae83647  
    2929        <div v-if="error" class="alert alert-danger auth-alert" role="alert">
    3030          <strong class="me-1">Oops.</strong>{{ error }}
     31        </div>
     32        <div v-if="forgotSuccess" class="alert alert-success auth-alert" role="alert">
     33          {{ forgotSuccess }}
    3134        </div>
    3235
     
    113116          <!-- Remember me -->
    114117          <div class="d-flex justify-content-between align-items-center mt-2 mb-3">
    115 
    116 
    117             <!-- enable later if you implement route -->
    118             <!-- <RouterLink class="link small accent" to="/forgot">Forgot password?</RouterLink> -->
     118            <span></span>
     119            <button class="link-button small accent" type="button" @click="toggleForgotPassword">
     120              Forgot password?
     121            </button>
    119122          </div>
    120123
     
    123126            <span v-if="loading" class="spinner-border spinner-border-sm me-2" aria-hidden="true"></span>
    124127            {{ loading ? 'Logging in…' : 'Log in' }}
     128          </button>
     129        </form>
     130
     131        <form v-if="showForgotPassword" class="forgot-panel mt-4" @submit.prevent="submitForgotPassword">
     132          <label class="form-label" for="forgot-identifier">Username or email</label>
     133          <div class="input-group auth-input">
     134            <span class="input-group-text">
     135              <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
     136                <path
     137                  d="M4 6.5A2.5 2.5 0 0 1 6.5 4h11A2.5 2.5 0 0 1 20 6.5v11a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 4 17.5v-11Zm2.5-.5a.5.5 0 0 0-.5.5v.8l6 3.7 6-3.7v-.8a.5.5 0 0 0-.5-.5h-11Zm11.5 3.6-5.5 3.4a1 1 0 0 1-1 0L6 9.6v7.9a.5.5 0 0 0 .5.5h11a.5.5 0 0 0 .5-.5V9.6Z"
     138                  fill="currentColor"
     139                  opacity=".85"
     140                />
     141              </svg>
     142            </span>
     143            <input
     144              id="forgot-identifier"
     145              v-model.trim="forgotIdentifier"
     146              class="form-control"
     147              type="text"
     148              autocomplete="username"
     149              required
     150              placeholder="username or email"
     151            />
     152          </div>
     153          <div v-if="forgotError" class="text-danger small mt-2">{{ forgotError }}</div>
     154          <button class="btn btn-outline-primary w-100 mt-3" type="submit" :disabled="forgotLoading">
     155            <span v-if="forgotLoading" class="spinner-border spinner-border-sm me-2" aria-hidden="true"></span>
     156            {{ forgotLoading ? 'Sending...' : 'Send temporary password' }}
    125157          </button>
    126158        </form>
     
    144176import { useRoute, useRouter } from 'vue-router'
    145177import { useAuthStore } from '../stores/auth'
     178import { forgotPassword } from '../api/auth'
    146179
    147180const auth = useAuthStore()
     
    153186const loading = ref(false)
    154187const error = ref<string | null>(null)
     188const forgotLoading = ref(false)
     189const forgotError = ref<string | null>(null)
     190const forgotSuccess = ref<string | null>(null)
     191const showForgotPassword = ref(false)
     192const forgotIdentifier = ref('')
    155193
    156194const showPassword = ref(false)
     
    159197function togglePassword() {
    160198  showPassword.value = !showPassword.value
     199}
     200
     201function toggleForgotPassword() {
     202  showForgotPassword.value = !showForgotPassword.value
     203  forgotError.value = null
     204  forgotSuccess.value = null
     205  if (showForgotPassword.value && !forgotIdentifier.value) {
     206    forgotIdentifier.value = username.value
     207  }
    161208}
    162209
     
    175222  } finally {
    176223    loading.value = false
     224  }
     225}
     226
     227async function submitForgotPassword() {
     228  forgotError.value = null
     229  forgotSuccess.value = null
     230  forgotLoading.value = true
     231  try {
     232    forgotSuccess.value = await forgotPassword({ identifier: forgotIdentifier.value })
     233    showForgotPassword.value = false
     234  } catch (e) {
     235    forgotError.value = e instanceof Error ? e.message : String(e)
     236  } finally {
     237    forgotLoading.value = false
    177238  }
    178239}
     
    276337}
    277338
     339.forgot-panel {
     340  border-top: 1px solid rgba(31, 41, 55, 0.1);
     341  padding-top: 1rem;
     342}
     343
    278344/* Input styling */
    279345.auth-input .input-group-text {
     
    371437}
    372438
     439.link-button {
     440  border: 0;
     441  background: transparent;
     442  padding: 0;
     443  text-decoration: none;
     444}
     445
     446.link-button.accent {
     447  color: #ff7a18;
     448  font-weight: 600;
     449}
     450
     451.link-button.accent:hover {
     452  color: #e76610;
     453}
     454
    373455/* Respect reduced motion */
    374456@media (prefers-reduced-motion: reduce) {
Note: See TracChangeset for help on using the changeset viewer.