Files
Siro/transit_dashboard/src/views/LoginView.vue
T

103 lines
3.7 KiB
Vue

<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '../stores/auth'
import * as transitApi from '../api/transit'
import { ApiError } from '../api/client'
const router = useRouter()
const auth = useAuthStore()
const step = ref('phone') // phone | otp
const phone = ref('')
const otp = ref('')
const loading = ref(false)
const error = ref('')
async function submitPhone() {
error.value = ''
if (!phone.value.trim()) { error.value = 'أدخل رقم الهاتف'; return }
loading.value = true
try {
await transitApi.loginRequest(phone.value.trim())
step.value = 'otp'
} catch (e) {
error.value = e instanceof ApiError ? e.message : 'حدث خطأ، حاول مجدداً'
} finally {
loading.value = false
}
}
async function submitOtp() {
error.value = ''
if (otp.value.trim().length < 3) { error.value = 'أدخل الرمز المكوّن من 3 أرقام'; return }
loading.value = true
try {
await auth.verifyOtp(phone.value.trim(), otp.value.trim())
router.replace('/dashboard')
} catch (e) {
error.value = e instanceof ApiError ? e.message : 'رمز غير صحيح أو منتهي'
} finally {
loading.value = false
}
}
</script>
<template>
<div class="login-page">
<div class="login-card card card-pad">
<div class="brand-mark">
<span class="brand-dot"></span>
<span>مواصلاتي</span>
</div>
<h1 class="title">لوحة مشرف المؤسسة</h1>
<p class="sub">الدخول عبر رقم الهاتف المسجَّل لدى فريق سيرو</p>
<form v-if="step === 'phone'" @submit.prevent="submitPhone" class="form">
<div class="field">
<label for="phone">رقم الهاتف</label>
<input id="phone" v-model="phone" class="input num" type="tel" placeholder="07XXXXXXXX" autofocus />
</div>
<p v-if="error" class="error">{{ error }}</p>
<button class="btn btn-primary" type="submit" :disabled="loading">
{{ loading ? 'جارٍ الإرسال...' : 'إرسال رمز التحقق' }}
</button>
</form>
<form v-else @submit.prevent="submitOtp" class="form">
<div class="field">
<label for="otp">رمز التحقق</label>
<input id="otp" v-model="otp" class="input num" type="text" inputmode="numeric" maxlength="3" placeholder="123" autofocus />
<span class="hint">أُرسل الرمز عبر واتساب إلى {{ phone }}</span>
</div>
<p v-if="error" class="error">{{ error }}</p>
<button class="btn btn-primary" type="submit" :disabled="loading">
{{ loading ? 'جارٍ التحقق...' : 'دخول' }}
</button>
<button class="btn btn-ghost" type="button" @click="step = 'phone'; otp = ''">
تغيير رقم الهاتف
</button>
</form>
</div>
</div>
</template>
<style scoped>
.login-page {
min-height: 100vh; display: flex; align-items: center; justify-content: center;
background: radial-gradient(120% 100% at 20% 0%, var(--brand-soft), var(--bg) 55%);
padding: 24px;
}
.login-card { width: 100%; max-width: 380px; }
.brand-mark {
display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 15px;
color: var(--brand-deep); margin-bottom: 28px;
}
.brand-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--brand); }
.title { font-size: 22px; margin-bottom: 6px; }
.sub { color: var(--ink-soft); font-size: 14px; margin: 0 0 26px; }
.form { display: flex; flex-direction: column; gap: 16px; }
.hint { font-size: 12.5px; color: var(--ink-faint); }
.error { color: var(--bad); font-size: 13.5px; margin: 0; }
</style>