2026-03-23 14:24:24 -07:00
|
|
|
<style scoped>
|
2026-03-27 14:06:50 -07:00
|
|
|
.login-container {
|
|
|
|
|
max-width: 900px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
}
|
|
|
|
|
.login-box {
|
|
|
|
|
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
.login-form-section {
|
|
|
|
|
padding: 40px;
|
|
|
|
|
}
|
|
|
|
|
.product-info-section {
|
|
|
|
|
padding: 40px;
|
|
|
|
|
background-color: #f8f9fa;
|
|
|
|
|
}
|
|
|
|
|
.login-header {
|
|
|
|
|
margin-bottom: 25px;
|
|
|
|
|
}
|
2026-03-23 14:24:24 -07:00
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
<div
|
|
|
|
|
class="container min-vh-100 d-flex align-items-center justify-content-center py-5"
|
|
|
|
|
>
|
|
|
|
|
<div class="login-container">
|
|
|
|
|
<div class="row login-box g-0">
|
|
|
|
|
<!-- Left side: Login Form -->
|
|
|
|
|
<div class="col-md-6 login-form-section">
|
|
|
|
|
<div class="login-header">
|
|
|
|
|
<h2>Welcome Back</h2>
|
|
|
|
|
<p class="text-muted">Please enter your credentials</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-04-16 17:14:57 +00:00
|
|
|
<div class="mb-3">
|
|
|
|
|
<label for="username" class="form-label">Username</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
class="form-control"
|
|
|
|
|
name="username"
|
|
|
|
|
required
|
|
|
|
|
v-model="username"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2026-03-23 14:24:24 -07:00
|
|
|
|
2026-04-16 17:14:57 +00:00
|
|
|
<div class="mb-3">
|
|
|
|
|
<label for="password" class="form-label">Password</label>
|
|
|
|
|
<input
|
|
|
|
|
type="password"
|
|
|
|
|
class="form-control"
|
|
|
|
|
name="password"
|
|
|
|
|
v-model="password"
|
|
|
|
|
required
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2026-03-23 14:24:24 -07:00
|
|
|
|
2026-04-16 17:14:57 +00:00
|
|
|
<!--
|
2026-03-23 14:24:24 -07:00
|
|
|
<div class="alert alert-danger" role="alert">
|
|
|
|
|
The credentials you provided weren't recognized.
|
|
|
|
|
</div>
|
|
|
|
|
-->
|
|
|
|
|
|
2026-04-16 17:14:57 +00:00
|
|
|
<div class="d-grid gap-2">
|
|
|
|
|
<ButtonLoading
|
|
|
|
|
@click="doLogin()"
|
|
|
|
|
:loading="loading"
|
|
|
|
|
text="Login"
|
|
|
|
|
variant="primary"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2026-03-23 14:24:24 -07:00
|
|
|
|
2026-04-16 17:14:57 +00:00
|
|
|
<div class="mt-3 text-center">
|
|
|
|
|
<p>Don't have an account? <a href="/signup">Sign up</a></p>
|
|
|
|
|
<a href="forgot-password.html">Forgot password?</a>
|
|
|
|
|
</div>
|
2026-04-20 22:34:39 +00:00
|
|
|
|
2026-04-23 15:24:06 +00:00
|
|
|
<div class="mt-3 text-center" v-if="isLoginSuccess">
|
|
|
|
|
<div class="alert alert-success">Login successful</div>
|
|
|
|
|
</div>
|
2026-04-20 22:34:39 +00:00
|
|
|
<div class="mt-3 text-center" v-if="error">
|
|
|
|
|
<div class="alert alert-danger">{{ error }}</div>
|
|
|
|
|
</div>
|
2026-03-23 14:24:24 -07:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Right side: Product Information -->
|
|
|
|
|
<div class="col-md-6 product-info-section">
|
|
|
|
|
<div>
|
|
|
|
|
<img src="/static/img/nidus-logo-256-transparent.png" />
|
|
|
|
|
<h2>Nidus Sync</h2>
|
|
|
|
|
<p class="lead mb-4">
|
|
|
|
|
All your field data, sync'd to all your techs
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<div class="mb-4">
|
|
|
|
|
<p>Something intelligent and intriguing</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="mb-4">
|
|
|
|
|
<h5>Key Features</h5>
|
|
|
|
|
<ul>
|
|
|
|
|
<li>Works with <b>Fieldseeker</b></li>
|
|
|
|
|
<li>Works <i>with</i> Fieldseeker</li>
|
|
|
|
|
<li><b>Works</b> with Fieldseeker</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
2026-04-16 17:14:57 +00:00
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { ref } from "vue";
|
|
|
|
|
import { apiClient } from "@/client";
|
|
|
|
|
import ButtonLoading from "@/components/common/ButtonLoading.vue";
|
2026-04-22 15:30:24 +00:00
|
|
|
import { useQueryParam } from "@/composable/use-query-param";
|
2026-04-22 14:31:05 +00:00
|
|
|
import { router } from "@/route/config";
|
2026-04-23 15:24:06 +00:00
|
|
|
import { useSessionStore } from "@/store/session";
|
2026-04-16 17:14:57 +00:00
|
|
|
|
2026-04-20 22:34:39 +00:00
|
|
|
const error = ref<string>("");
|
2026-04-23 15:24:06 +00:00
|
|
|
const isLoginSuccess = ref<boolean>(false);
|
2026-04-16 17:14:57 +00:00
|
|
|
const loading = ref<boolean>(false);
|
2026-04-22 15:30:24 +00:00
|
|
|
const paramNext = useQueryParam("next");
|
2026-04-16 17:14:57 +00:00
|
|
|
const password = ref<string>("");
|
2026-04-23 15:24:06 +00:00
|
|
|
const session = useSessionStore();
|
2026-04-16 17:14:57 +00:00
|
|
|
const username = ref<string>("");
|
|
|
|
|
async function doLogin() {
|
2026-04-23 15:24:06 +00:00
|
|
|
if (username.value == "" && password.value == "") {
|
|
|
|
|
error.value =
|
|
|
|
|
"Slow down there partner, you should add a username and password first.";
|
|
|
|
|
return;
|
|
|
|
|
} else if (username.value == "") {
|
|
|
|
|
error.value = "Your username is empty - we've got to know who you are.";
|
|
|
|
|
return;
|
|
|
|
|
} else if (password.value == "") {
|
|
|
|
|
error.value = "Your password is empty - you've got to put something there.";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-16 17:14:57 +00:00
|
|
|
loading.value = true;
|
2026-04-23 15:24:06 +00:00
|
|
|
error.value = "";
|
2026-04-16 17:14:57 +00:00
|
|
|
try {
|
2026-04-23 15:24:06 +00:00
|
|
|
const resp = await session.doSignin(password.value, username.value);
|
|
|
|
|
isLoginSuccess.value = resp.is_success;
|
|
|
|
|
if (resp.status == 200) {
|
|
|
|
|
if (paramNext.value.value && paramNext.value.value != "/signin") {
|
|
|
|
|
router.push(paramNext.value.value);
|
|
|
|
|
} else {
|
|
|
|
|
router.push("/");
|
|
|
|
|
}
|
|
|
|
|
} else if (resp.status == 401) {
|
|
|
|
|
error.value = "Invalid credentials";
|
2026-04-22 15:30:24 +00:00
|
|
|
} else {
|
2026-04-23 15:24:06 +00:00
|
|
|
error.value = `Status ${resp.status}`;
|
2026-04-22 15:30:24 +00:00
|
|
|
}
|
2026-04-16 17:14:57 +00:00
|
|
|
} catch (e) {
|
|
|
|
|
console.log("login failed", e);
|
2026-04-20 22:34:39 +00:00
|
|
|
error.value = `Login failed: ${e}`;
|
2026-04-16 17:14:57 +00:00
|
|
|
} finally {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|