Update navigation to accept the slug as part of the URL
Some checks failed
Check usage of free licenses / build-static-assets (pull_request) Successful in 44s
Add copyright notice / copyright_notice (pull_request) Successful in 54s
Playwright Tests / test (pull_request) Failing after 8m28s

This commit is contained in:
Manuel Bustillo 2024-12-01 18:02:25 +01:00
parent 0ef310fecd
commit 82f5dd6c64
15 changed files with 29 additions and 19 deletions

View File

@ -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">

View File

@ -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(),

View File

@ -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({

View File

@ -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) => {

View File

@ -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(),

View File

@ -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) => {

View File

@ -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';

View File

@ -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

View File

@ -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 },
]; ];

View File

@ -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()}`);
} }
}); });
}} }}