internal/dashboard/frontend/src/views/LoginView.vue

<script setup lang="ts">
import { IconLogin } from "@tabler/icons-vue";
import { onBeforeUnmount, ref } from "vue";
import { useRouter } from "vue-router";
import SectionCard from "../components/SectionCard.vue";
import { fetchHoneypotTypes, useAuthStore } from "../store";

const authStore = useAuthStore();
const router = useRouter();
const password = ref("");
const error = ref("");
const loading = ref(false);

const handleLogin = async () => {
  loading.value = true;
  error.value = "";
  try {
    const success = await authStore.login(password.value);
    if (success) {
      router.push("/");
    } else {
      error.value = "Invalid password";
    }
  } catch (e) {
    error.value = "An error occurred";
  } finally {
    loading.value = false;
  }
};

onBeforeUnmount(() => {
  fetchHoneypotTypes();
});
</script>

<template>
  <div class="flex flex-1 items-center justify-center p-6">
    <SectionCard class="w-full max-w-md">
      <div class="mb-6 text-center">
        <h1
          class="text-primary-600 font-mono text-2xl font-medium tracking-tight uppercase"
        >
          <strong>Honey</strong><em>pie</em>
        </h1>
        <p class="text-muted text-sm">Dashboard Login</p>
      </div>

      <form @submit.prevent="handleLogin" class="space-y-4">
        <div>
          <label
            for="password"
            class="sr-only mb-1 block text-sm font-medium text-stone-400"
          >
            Password
          </label>
          <input
            id="password"
            v-model="password"
            type="password"
            required
            class="focus:border-primary-600 focus:ring-primary-600 w-full rounded-md border border-stone-700 bg-stone-900 px-3 py-2 font-mono text-stone-200 focus:ring-1 focus:outline-none"
            placeholder="Enter dashboard password"
            autofocus
          />
        </div>

        <div v-if="error" class="text-sm font-bold text-red-500">
          {{ error }}
        </div>

        <button
          type="submit"
          :disabled="loading"
          class="bg-primary-600 hover:bg-primary-700 mx-auto rounded-md px-4 py-2 font-medium text-white transition-colors disabled:opacity-50"
        >
          <IconLogin size="20" /> {{ loading ? "Logging in..." : "Login" }}
        </button>
      </form>
    </SectionCard>
  </div>
</template>

<style scoped>
@reference "src/style.css";
</style>