Define a basic login form with redirection to the Dashboard #127
| @ -1,12 +1,15 @@ | |||||||
| /* Copyright (C) 2024 Manuel Bustillo*/ | /* Copyright (C) 2024 Manuel Bustillo*/ | ||||||
| 
 | 
 | ||||||
|  | 'use client';  | ||||||
| import Link from 'next/link'; | import Link from 'next/link'; | ||||||
| import styles from '@/app/ui/home.module.css'; | import styles from '@/app/ui/home.module.css'; | ||||||
| import LoginForm from '@/app/ui/components/login-form'; | import LoginForm from '@/app/ui/components/login-form'; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| export default function Page() { | export default async function Page({ params }: { params: Promise<{ slug: string }> }) { | ||||||
|  | 
 | ||||||
|  |   localStorage.setItem('slug', (await params).slug) | ||||||
|   return ( |   return ( | ||||||
|     <main className="flex min-h-screen flex-col p-6"> |     <main className="flex min-h-screen flex-col p-6"> | ||||||
|       <div className="flex flex-row"> |       <div className="flex flex-row"> | ||||||
| @ -1,11 +1,11 @@ | |||||||
| /* Copyright (C) 2024 Manuel Bustillo*/ | /* Copyright (C) 2024 Manuel Bustillo*/ | ||||||
| 
 | 
 | ||||||
| import { getCsrfToken } from '@/app/lib/utils'; | import { getCsrfToken, getSlug } from '@/app/lib/utils'; | ||||||
| import { User } from '@/app/lib/definitions'; | import { User } from '@/app/lib/definitions'; | ||||||
| 
 | 
 | ||||||
| export function login({ email, password, onLogin }: { email: string, password: string, onLogin: (user: User) => void }) { | export function login({ email, password, onLogin }: { email: string, password: string, onLogin: (user: User) => void }) { | ||||||
|   console.log(email, password); |   console.log(email, password); | ||||||
|   return fetch("/api/default/users/sign_in", { |   return fetch(`/api/${getSlug()}/users/sign_in`, { | ||||||
|     method: 'POST', |     method: 'POST', | ||||||
|     body: JSON.stringify({ user: { email, password } }), |     body: JSON.stringify({ user: { email, password } }), | ||||||
|     headers: { |     headers: { | ||||||
| @ -26,7 +26,7 @@ export function login({ email, password, onLogin }: { email: string, password: s | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function logout({ onLogout }: { onLogout: () => void }) { | export function logout({ onLogout }: { onLogout: () => void }) { | ||||||
|   fetch("/api/default/users/sign_out", { |   fetch(`/api/${getSlug()}/users/sign_out`, { | ||||||
|     method: 'DELETE', |     method: 'DELETE', | ||||||
|     headers: { |     headers: { | ||||||
|       'X-CSRF-TOKEN': getCsrfToken(), |       'X-CSRF-TOKEN': getCsrfToken(), | ||||||
|  | |||||||
| @ -1,10 +1,10 @@ | |||||||
| /* Copyright (C) 2024 Manuel Bustillo*/ | /* Copyright (C) 2024 Manuel Bustillo*/ | ||||||
| 
 | 
 | ||||||
| import { Expense } from '@/app/lib/definitions'; | import { Expense } from '@/app/lib/definitions'; | ||||||
| import { getCsrfToken } from '@/app/lib/utils'; | import { getCsrfToken, getSlug } from '@/app/lib/utils'; | ||||||
| 
 | 
 | ||||||
| export function loadExpenses(onLoad?: (expenses: Expense[]) => void) { | export function loadExpenses(onLoad?: (expenses: Expense[]) => void) { | ||||||
|   fetch("/api/default/expenses") |   fetch(`/api/${getSlug()}/expenses`) | ||||||
|     .then((response) => response.json()) |     .then((response) => response.json()) | ||||||
|     .then((data) => { |     .then((data) => { | ||||||
|       onLoad && onLoad(data.map((record: any) => { |       onLoad && onLoad(data.map((record: any) => { | ||||||
| @ -21,7 +21,7 @@ export function loadExpenses(onLoad?: (expenses: Expense[]) => void) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function updateExpense(expense: Expense) { | export function updateExpense(expense: Expense) { | ||||||
|   fetch(`/api/default/expenses/${expense.id}`, |   fetch(`/api/${getSlug()}/expenses/${expense.id}`, | ||||||
|     { |     { | ||||||
|       method: 'PUT', |       method: 'PUT', | ||||||
|       body: JSON.stringify({ |       body: JSON.stringify({ | ||||||
|  | |||||||
| @ -1,9 +1,10 @@ | |||||||
| /* Copyright (C) 2024 Manuel Bustillo*/ | /* Copyright (C) 2024 Manuel Bustillo*/ | ||||||
| 
 | 
 | ||||||
| import { Group } from '@/app/lib/definitions'; | import { Group } from '@/app/lib/definitions'; | ||||||
|  | import { getSlug } from '../lib/utils'; | ||||||
| 
 | 
 | ||||||
| export function loadGroups(onLoad?: (groups: Group[]) => void) { | export function loadGroups(onLoad?: (groups: Group[]) => void) { | ||||||
|   fetch("/api/default/groups") |   fetch(`/api/${getSlug()}/groups`) | ||||||
|     .then((response) => response.json()) |     .then((response) => response.json()) | ||||||
|     .then((data) => { |     .then((data) => { | ||||||
|       onLoad && onLoad(data.map((record: any) => { |       onLoad && onLoad(data.map((record: any) => { | ||||||
|  | |||||||
| @ -1,10 +1,10 @@ | |||||||
| /* Copyright (C) 2024 Manuel Bustillo*/ | /* Copyright (C) 2024 Manuel Bustillo*/ | ||||||
| 
 | 
 | ||||||
| import { Guest } from '@/app/lib/definitions'; | import { Guest } from '@/app/lib/definitions'; | ||||||
| import { getCsrfToken } from '@/app/lib/utils'; | import { getCsrfToken, getSlug } from '@/app/lib/utils'; | ||||||
| 
 | 
 | ||||||
| export function loadGuests(onLoad?: (guests: Guest[]) => void) { | export function loadGuests(onLoad?: (guests: Guest[]) => void) { | ||||||
|   fetch("/api/default/guests") |   fetch(`/api/${getSlug()}/guests`) | ||||||
|     .then((response) => response.json()) |     .then((response) => response.json()) | ||||||
|     .then((data) => { |     .then((data) => { | ||||||
|       onLoad && onLoad(data.map((record: any) => { |       onLoad && onLoad(data.map((record: any) => { | ||||||
| @ -22,7 +22,7 @@ export function loadGuests(onLoad?: (guests: Guest[]) => void) { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export function updateGuest(guest: Guest) { | export function updateGuest(guest: Guest) { | ||||||
|   return fetch(`/api/default/guests/${guest.id}`, |   return fetch(`/api/${getSlug()}/guests/${guest.id}`, | ||||||
|     { |     { | ||||||
|       method: 'PUT', |       method: 'PUT', | ||||||
|       body: JSON.stringify({ guest: { name: guest.name, status: guest.status } }), |       body: JSON.stringify({ guest: { name: guest.name, status: guest.status } }), | ||||||
| @ -35,7 +35,7 @@ export function updateGuest(guest: Guest) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function createGuest(name: string, group_id: string, onCreate?: () => void) { | export function createGuest(name: string, group_id: string, onCreate?: () => void) { | ||||||
|   fetch("/api/default/guests", { |   fetch(`/api/${getSlug()}/guests`, { | ||||||
|     method: 'POST', |     method: 'POST', | ||||||
|     body: JSON.stringify({ name: name, group_id: group_id }), |     body: JSON.stringify({ name: name, group_id: group_id }), | ||||||
|     headers: { |     headers: { | ||||||
| @ -51,7 +51,7 @@ export function createGuest(name: string, group_id: string, onCreate?: () => voi | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function destroyGuest(guest: Guest, onDestroy?: () => void) { | export function destroyGuest(guest: Guest, onDestroy?: () => void) { | ||||||
|   fetch(`/api/default/guests/${guest.id}`, { |   fetch(`/api/${getSlug()}/guests/${guest.id}`, { | ||||||
|     method: 'DELETE', |     method: 'DELETE', | ||||||
|     headers: { |     headers: { | ||||||
|       'X-CSRF-TOKEN': getCsrfToken(), |       'X-CSRF-TOKEN': getCsrfToken(), | ||||||
|  | |||||||
| @ -1,9 +1,10 @@ | |||||||
| /* Copyright (C) 2024 Manuel Bustillo*/ | /* Copyright (C) 2024 Manuel Bustillo*/ | ||||||
| 
 | 
 | ||||||
| import { TableArrangement } from '@/app/lib/definitions'; | import { TableArrangement } from '@/app/lib/definitions'; | ||||||
|  | import { getSlug } from '../lib/utils'; | ||||||
| 
 | 
 | ||||||
| export function loadTableSimulations(onLoad?: (tableSimulations: TableArrangement[]) => void) { | export function loadTableSimulations(onLoad?: (tableSimulations: TableArrangement[]) => void) { | ||||||
|   fetch('/api/default/tables_arrangements') |   fetch(`/api/${getSlug()}/tables_arrangements`) | ||||||
|     .then((response) => response.json()) |     .then((response) => response.json()) | ||||||
|     .then((data) => { |     .then((data) => { | ||||||
|       onLoad && onLoad(data.map((record: any) => { |       onLoad && onLoad(data.map((record: any) => { | ||||||
|  | |||||||
| @ -6,3 +6,5 @@ export const getCsrfToken = () => { | |||||||
|       .find((row) => row.startsWith("csrf-token")) |       .find((row) => row.startsWith("csrf-token")) | ||||||
|       ?.split("=")[1] || 'unknown'; |       ?.split("=")[1] || 'unknown'; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | export const getSlug = () => localStorage.getItem('slug') || 'default'; | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ import { useState, useEffect } from 'react'; | |||||||
| import { classNames } from './button'; | import { classNames } from './button'; | ||||||
| import { useRouter } from 'next/navigation' | import { useRouter } from 'next/navigation' | ||||||
| import { User } from '../../lib/definitions'; | import { User } from '../../lib/definitions'; | ||||||
|  | import { getSlug } from '@/app/lib/utils'; | ||||||
| 
 | 
 | ||||||
| export default function LoginForm() { | export default function LoginForm() { | ||||||
|   const [email, setEmail] = useState(""); |   const [email, setEmail] = useState(""); | ||||||
| @ -40,7 +41,7 @@ export default function LoginForm() { | |||||||
|           password: password, |           password: password, | ||||||
|           onLogin: (user) => { |           onLogin: (user) => { | ||||||
|             setCurrentUser(user); |             setCurrentUser(user); | ||||||
|             router.push('/dashboard') |             router.push(`${getSlug()}/dashboard`) | ||||||
|           } |           } | ||||||
|         })}> |         })}> | ||||||
|         Sign in |         Sign in | ||||||
|  | |||||||
| @ -10,13 +10,14 @@ import { | |||||||
| import Link from 'next/link'; | import Link from 'next/link'; | ||||||
| import { usePathname } from 'next/navigation'; | import { usePathname } from 'next/navigation'; | ||||||
| import clsx from 'clsx'; | import clsx from 'clsx'; | ||||||
|  | import { getSlug } from '@/app/lib/utils'; | ||||||
| 
 | 
 | ||||||
| // Map of links to display in the side navigation.
 | // Map of links to display in the side navigation.
 | ||||||
| // Depending on the size of the application, this would be stored in a database.
 | // Depending on the size of the application, this would be stored in a database.
 | ||||||
| const links = [ | const links = [ | ||||||
|   { name: 'Guests', href: '/dashboard/guests', icon: UserGroupIcon }, |   { name: 'Guests', href: `/${getSlug()}/dashboard/guests`, icon: UserGroupIcon }, | ||||||
|   { name: 'Expenses', href: '/dashboard/expenses', icon: BanknotesIcon }, |   { name: 'Expenses', href: `/${getSlug()}/dashboard/expenses`, icon: BanknotesIcon }, | ||||||
|   { name: 'Table distributions', href: '/dashboard/tables', icon: RectangleGroupIcon }, |   { name: 'Table distributions', href: `/${getSlug()}/dashboard/tables`, icon: RectangleGroupIcon }, | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import { PowerIcon } from '@heroicons/react/24/outline'; | |||||||
| import { gloriaHallelujah } from '@/app/ui/fonts'; | import { gloriaHallelujah } from '@/app/ui/fonts'; | ||||||
| import { logout } from '@/app/api/authentication'; | import { logout } from '@/app/api/authentication'; | ||||||
| import { useRouter } from 'next/navigation'; | import { useRouter } from 'next/navigation'; | ||||||
|  | import { getSlug } from '@/app/lib/utils'; | ||||||
| 
 | 
 | ||||||
| export default function SideNav() { | export default function SideNav() { | ||||||
|   const router = useRouter(); |   const router = useRouter(); | ||||||
| @ -32,7 +33,7 @@ export default function SideNav() { | |||||||
|             logout({ |             logout({ | ||||||
|               onLogout: () => { |               onLogout: () => { | ||||||
|                 localStorage.clear(); |                 localStorage.clear(); | ||||||
|                 router.push('/'); |                 router.push(`/${getSlug()}`); | ||||||
|               } |               } | ||||||
|             }); |             }); | ||||||
|           }} |           }} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user