Frontend working. Added form vendor profilke
This commit is contained in:
@@ -1,6 +1,41 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
import { writable } from "svelte/store";
|
||||||
|
import type { Writable } from 'svelte/store';
|
||||||
import '../../app.postcss'; // Import Tailwind CSS
|
import '../../app.postcss'; // Import Tailwind CSS
|
||||||
|
import { user } from '$lib/states';
|
||||||
|
|
||||||
|
// Define the type for the user store
|
||||||
|
interface User {
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placeholder for user store - in a real app, this would be managed by an auth library or context
|
||||||
|
let storedUser: User | null = null;
|
||||||
|
|
||||||
|
// Check for user session on mount (this is a placeholder, actual implementation may vary)
|
||||||
|
onMount(() => {
|
||||||
|
const storedUserString = localStorage.getItem('user');
|
||||||
|
if (storedUserString) {
|
||||||
|
storedUser = JSON.parse(storedUserString);
|
||||||
|
user.set(storedUser);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
user.subscribe((newUser) => {
|
||||||
|
if (newUser) {
|
||||||
|
storedUser = newUser;
|
||||||
|
} else {
|
||||||
|
storedUser = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Logout function
|
||||||
|
const logout = () => {
|
||||||
|
user.set(null);
|
||||||
|
localStorage.removeItem('user');
|
||||||
|
window.location.href = '/';
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="min-h-screen bg-white flex flex-col">
|
<div class="min-h-screen bg-white flex flex-col">
|
||||||
@@ -8,6 +43,21 @@
|
|||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<a href="/" class="btn btn-ghost normal-case text-xl">Heating Price Hero</a>
|
<a href="/" class="btn btn-ghost normal-case text-xl">Heating Price Hero</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex-none">
|
||||||
|
{#if $user}
|
||||||
|
<div class="dropdown dropdown-end">
|
||||||
|
<button type="button" class="btn btn-ghost normal-case text-lg">
|
||||||
|
{$user.username}
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||||
|
<li><a href="/vendor">Dashboard</a></li>
|
||||||
|
<li><button type="button" on:click={logout}>Logout</button></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<a href="/login" class="btn btn-ghost normal-case text-lg">Dealer Login</a>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="flex-grow container mx-auto p-4">
|
<main class="flex-grow container mx-auto p-4">
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
import { user } from '$lib/states';
|
||||||
import type { LoginRequest } from '$lib/types/types';
|
import type { LoginRequest } from '$lib/types/types';
|
||||||
|
|
||||||
let username = '';
|
let username = '';
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
errorMessage = '';
|
errorMessage = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/login', {
|
const response = await fetch('http://localhost:9552/auth/login', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@@ -31,8 +32,18 @@
|
|||||||
} else {
|
} else {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
// Assuming the backend returns a token or some success indicator
|
// Assuming the backend returns a token or some success indicator
|
||||||
// Redirect to home page or dashboard after successful login
|
// Store the token in localStorage for authentication checks
|
||||||
goto('/');
|
if (data.token) {
|
||||||
|
localStorage.setItem('auth_token', data.token);
|
||||||
|
}
|
||||||
|
// Store the user object in localStorage
|
||||||
|
localStorage.setItem('user', JSON.stringify(data.user));
|
||||||
|
|
||||||
|
// Update the user store
|
||||||
|
user.set(data.user);
|
||||||
|
|
||||||
|
// Redirect to vendor page after successful login
|
||||||
|
goto('/vendor');
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
errorMessage = 'An error occurred. Please try again.';
|
errorMessage = 'An error occurred. Please try again.';
|
||||||
@@ -107,5 +118,10 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<div class="mt-4 text-center">
|
||||||
|
<p class="text-sm text-gray-600">
|
||||||
|
Not registered yet? <a href="/register" class="font-medium text-indigo-600 hover:text-indigo-500">Register here</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
errorMessage = '';
|
errorMessage = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/register', {
|
const response = await fetch('http://localhost:9552/auth/register', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@@ -38,11 +38,17 @@
|
|||||||
const errorData = await response.json();
|
const errorData = await response.json();
|
||||||
errorMessage = errorData.error || 'Registration failed';
|
errorMessage = errorData.error || 'Registration failed';
|
||||||
} else {
|
} else {
|
||||||
// Redirect to login or home page after successful registration
|
const data = await response.json();
|
||||||
goto('/login');
|
// Store the token in localStorage for authentication checks
|
||||||
|
if (data.token) {
|
||||||
|
localStorage.setItem('auth_token', data.token);
|
||||||
|
}
|
||||||
|
// Redirect to vendor page after successful registration
|
||||||
|
goto('/vendor');
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
errorMessage = 'An error occurred. Please try again.';
|
console.error('Registration error:', err);
|
||||||
|
errorMessage = 'An error occurred. Please try again. Check the console for details.';
|
||||||
} finally {
|
} finally {
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/routes/(app)/vendor/+layout.svelte
vendored
Normal file
16
src/routes/(app)/vendor/+layout.svelte
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { goto } from '$app/navigation';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
// Check if the user is logged in by looking for a token in localStorage or a cookie
|
||||||
|
// This assumes a token is stored upon successful login
|
||||||
|
const token = localStorage.getItem('auth_token');
|
||||||
|
if (!token) {
|
||||||
|
// Redirect to home page if not logged in
|
||||||
|
goto('/');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<slot />
|
||||||
12
src/routes/(app)/vendor/+page.svelte
vendored
Normal file
12
src/routes/(app)/vendor/+page.svelte
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
// Vendor page logic can be added here
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="container mx-auto p-4">
|
||||||
|
<h1 class="text-3xl font-bold mb-4">Vendor Dashboard</h1>
|
||||||
|
<p>Welcome to the Vendor section. Navigate to specific pages using the links below.</p>
|
||||||
|
<div class="mt-4">
|
||||||
|
<a href="/vendor/profile" class="text-blue-500 hover:underline">Profile</a>
|
||||||
|
<a href="/vendor/price" class="text-blue-500 hover:underline ml-4">Price</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
11
src/routes/(app)/vendor/price/+page.svelte
vendored
Normal file
11
src/routes/(app)/vendor/price/+page.svelte
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
// Vendor price page logic can be added here
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="container mx-auto p-4">
|
||||||
|
<h1 class="text-3xl font-bold mb-4">Vendor Price Management</h1>
|
||||||
|
<p>This is the Vendor Price page. Here you can manage pricing information.</p>
|
||||||
|
<div class="mt-4">
|
||||||
|
<a href="/vendor" class="text-blue-500 hover:underline">Back to Vendor Dashboard</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
49
src/routes/(app)/vendor/profile/+page.svelte
vendored
Normal file
49
src/routes/(app)/vendor/profile/+page.svelte
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
// Vendor profile page logic can be added here
|
||||||
|
const states = ['ME', 'NH', 'VT', 'MA', 'RI', 'CT'];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="container mx-auto p-4">
|
||||||
|
<h1 class="text-3xl font-bold mb-4">Vendor Profile</h1>
|
||||||
|
<form class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label for="companyName" class="block text-gray-700 text-sm font-bold mb-2">Company Name:</label>
|
||||||
|
<input type="text" id="companyName" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="address" class="block text-gray-700 text-sm font-bold mb-2">Address:</label>
|
||||||
|
<input type="text" id="address" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="town" class="block text-gray-700 text-sm font-bold mb-2">Town:</label>
|
||||||
|
<input type="text" id="town" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="state" class="block text-gray-700 text-sm font-bold mb-2">State:</label>
|
||||||
|
<select id="state" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
|
||||||
|
{#each states as state}
|
||||||
|
<option value={state}>{state}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="phone" class="block text-gray-700 text-sm font-bold mb-2">Phone:</label>
|
||||||
|
<input type="text" id="phone" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="ownerName" class="block text-gray-700 text-sm font-bold mb-2">Owner Name:</label>
|
||||||
|
<input type="text" id="ownerName" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="ownerPhoneNumber" class="block text-gray-700 text-sm font-bold mb-2">Owner Phone Number:</label>
|
||||||
|
<input type="text" id="ownerPhoneNumber" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="email" class="block text-gray-700 text-sm font-bold mb-2">Email:</label>
|
||||||
|
<input type="email" id="email" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="mt-4">
|
||||||
|
<a href="/vendor" class="text-blue-500 hover:underline">Back to Vendor Dashboard</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
16
src/routes/+error.svelte
Normal file
16
src/routes/+error.svelte
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="min-h-screen bg-white flex flex-col items-center justify-center p-4">
|
||||||
|
<h1 class="text-6xl font-bold text-primary">{$page.status}</h1>
|
||||||
|
<p class="text-2xl text-base-content mt-4">
|
||||||
|
{#if $page.status === 404}
|
||||||
|
Page Not Found
|
||||||
|
{:else}
|
||||||
|
An error occurred
|
||||||
|
{/if}
|
||||||
|
</p>
|
||||||
|
<p class="text-base text-base-content mt-2">{$page.error?.message || 'Something went wrong.'}</p>
|
||||||
|
<a href="/" class="btn btn-primary mt-6">Go Home</a>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user