feat(frontend): Vue 3 + wa-sqlite + sync engine + auth + layouts
- package.json with Vue 3, Pinia, vue-router, wa-sqlite, Tailwind CSS 4, Vite - wa-sqlite database layer with IDBBatchAtomicVFS (offline-first) - Full schema mirroring backend tables (vehicles, orders, invoices, etc.) - SyncEngine: fullSync, incrementalSync, pushQueue for offline queue - Auth store with JWT parsing, login/register, plan tier detection - Router with all routes and auth navigation guards - AppLayout (sidebar desktop / bottom nav mobile) + AuthLayout - Login/Register views connected to API contract - SyncIndicator component (online/offline status) - Reactive SQL query composable (useSqlQuery) - Placeholder views for dashboard, orders, vehicles, appointments, catalog, settings Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
93
frontend/src/views/auth/RegisterView.vue
Normal file
93
frontend/src/views/auth/RegisterView.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<h2 class="text-xl font-semibold mb-6">Inregistrare</h2>
|
||||
<form @submit.prevent="handleRegister" class="space-y-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Numele service-ului</label>
|
||||
<input
|
||||
v-model="tenantName"
|
||||
type="text"
|
||||
required
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="Service Auto Ionescu"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Telefon</label>
|
||||
<input
|
||||
v-model="telefon"
|
||||
type="tel"
|
||||
required
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="0722 000 000"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Email</label>
|
||||
<input
|
||||
v-model="email"
|
||||
type="email"
|
||||
required
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="email@exemplu.ro"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Parola</label>
|
||||
<input
|
||||
v-model="password"
|
||||
type="password"
|
||||
required
|
||||
minlength="6"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="Minim 6 caractere"
|
||||
/>
|
||||
</div>
|
||||
<p v-if="error" class="text-sm text-red-600">{{ error }}</p>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="loading"
|
||||
class="w-full py-2 px-4 bg-blue-600 text-white rounded-md hover:bg-blue-700 disabled:opacity-50"
|
||||
>
|
||||
{{ loading ? 'Se creeaza contul...' : 'Creeaza cont (trial 30 zile)' }}
|
||||
</button>
|
||||
</form>
|
||||
<p class="mt-4 text-center text-sm text-gray-500">
|
||||
Ai deja cont?
|
||||
<router-link to="/login" class="text-blue-600 hover:underline">Autentificare</router-link>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAuthStore } from '../../stores/auth.js'
|
||||
import { initDatabase } from '../../db/database.js'
|
||||
import { syncEngine } from '../../db/sync.js'
|
||||
|
||||
const router = useRouter()
|
||||
const auth = useAuthStore()
|
||||
|
||||
const tenantName = ref('')
|
||||
const telefon = ref('')
|
||||
const email = ref('')
|
||||
const password = ref('')
|
||||
const error = ref('')
|
||||
const loading = ref(false)
|
||||
|
||||
async function handleRegister() {
|
||||
error.value = ''
|
||||
loading.value = true
|
||||
try {
|
||||
await auth.register(email.value, password.value, tenantName.value, telefon.value)
|
||||
await initDatabase()
|
||||
syncEngine.fullSync()
|
||||
router.push('/dashboard')
|
||||
} catch (e) {
|
||||
error.value = e.message
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user