Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 41 additions & 44 deletions backend/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ definitions:
CreateGuest:
properties:
first_name:
example: John
example: Jane
type: string
last_name:
example: Doe
Expand All @@ -17,9 +17,6 @@ definitions:
type: object
CreateUser:
properties:
clerk_id:
example: user_123
type: string
department:
example: Housekeeping
type: string
Expand All @@ -29,6 +26,9 @@ definitions:
first_name:
example: John
type: string
id:
example: user_123
type: string
last_name:
example: Doe
type: string
Expand Down Expand Up @@ -69,7 +69,7 @@ definitions:
example: "2024-01-02T00:00:00Z"
type: string
first_name:
example: John
example: Jane
type: string
id:
example: 530e8400-e458-41d4-a716-446655440000
Expand Down Expand Up @@ -219,7 +219,7 @@ definitions:
UpdateGuest:
properties:
first_name:
example: John
example: Jane
type: string
last_name:
example: Doe
Expand All @@ -233,9 +233,6 @@ definitions:
type: object
User:
properties:
clerk_id:
example: user_123
type: string
created_at:
example: "2024-01-01T00:00:00Z"
type: string
Expand All @@ -249,7 +246,7 @@ definitions:
example: John
type: string
id:
example: 550e8400-e29b-41d4-a716-446655440000
example: user_123
type: string
last_name:
example: Doe
Expand Down Expand Up @@ -401,6 +398,40 @@ paths:
summary: Updates a guest
tags:
- guests
/api/v1/hotels:
post:
consumes:
- application/json
description: Create a new hotel with the given data
parameters:
- description: Hotel data
in: body
name: hotel
required: true
schema:
$ref: '#/definitions/Hotel'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/Hotel'
"400":
description: Bad Request
schema:
additionalProperties:
type: string
type: object
"500":
description: Internal Server Error
schema:
additionalProperties:
type: string
type: object
summary: Create hotel
tags:
- hotels
/api/v1/hotels/{id}:
get:
description: Retrieve a hotel's details using its UUID
Expand Down Expand Up @@ -499,40 +530,6 @@ paths:
summary: Get personalized hello message
tags:
- hello
/hotel:
post:
consumes:
- application/json
description: Create a new hotel with the given data
parameters:
- description: Hotel data
in: body
name: hotel
required: true
schema:
$ref: '#/definitions/Hotel'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/Hotel'
"400":
description: Bad Request
schema:
additionalProperties:
type: string
type: object
"500":
description: Internal Server Error
schema:
additionalProperties:
type: string
type: object
summary: Create hotel
tags:
- hotels
/request:
post:
consumes:
Expand Down
4 changes: 2 additions & 2 deletions backend/internal/models/guests.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ type CreateGuest struct {
LastName string `json:"last_name" validate:"notblank" example:"Doe"`
ProfilePicture *string `json:"profile_picture,omitempty" validate:"omitempty,url" example:"https://example.com/john.jpg"`
Timezone *string `json:"timezone,omitempty" validate:"omitempty,timezone" example:"America/New_York"`
}
}//@name CreateGuest

type UpdateGuest struct {
FirstName string `json:"first_name" validate:"notblank" example:"Jane"`
LastName string `json:"last_name" validate:"notblank" example:"Doe"`
ProfilePicture *string `json:"profile_picture,omitempty" validate:"omitempty,url" example:"https://example.com/john.jpg"`
Timezone *string `json:"timezone,omitempty" validate:"omitempty,timezone" example:"America/New_York"`
}
}//@name UpdateGuest

type Guest struct {
ID string `json:"id" example:"530e8400-e458-41d4-a716-446655440000"`
Expand Down
2 changes: 1 addition & 1 deletion clients/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export {
} from "./api/generated/endpoints/users/users";

export {
usePostHotel,
usePostApiV1Hotels,
useGetApiV1HotelsId,
} from "./api/generated/endpoints/hotels/hotels";

Expand Down
2 changes: 1 addition & 1 deletion clients/web/src/components/SideBarWithContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function SideBarWithContent() {
return (
<div className="flex min-h-screen">
<Sidebar />
<main className="flex-1 p-6">
<main className="flex-1">
<Outlet />
</main>
</div>
Expand Down
51 changes: 51 additions & 0 deletions clients/web/src/components/ui/PageShell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { ReactNode } from 'react'
import { cn } from '@/lib/utils'

type PageShellProps = {
header: ReactNode
drawer?: ReactNode
drawerOpen?: boolean
children: ReactNode
}

export function PageShell({
header,
drawer,
drawerOpen = false,
children,
}: PageShellProps) {
const hasDrawer = !!drawer

return (
<main className="flex h-screen overflow-hidden">
<div
className={cn(
'shrink-0 flex flex-col overflow-hidden transition-[flex-basis] duration-300 ease-in-out',
hasDrawer && drawerOpen ? 'basis-2/5' : 'basis-full',
)}
>
<header className="shrink-0 bg-gray-100 h-[10vh] px-[4vw]">
{header}
</header>

<section className="flex-1 min-h-0 overflow-auto bg-white-100 px-[4vw] py-[2vh]">
<div className="mx-auto flex w-full max-w-[94vw] flex-col">
{children}
</div>
</section>
</div>

{hasDrawer && (
<aside
className={cn(
'shrink-0 overflow-hidden transition-[flex-basis] duration-300 ease-in-out shadow-xl shadow-black/25 px-[4vw] py-[3vh]',
drawerOpen ? 'basis-3/5' : 'basis-0',
)}
>
{/* Nested div to a fixed width to avoid animation issues */}
<div className="h-full w-[60vw]">{drawer}</div>
</aside>
)}
</main>
)
}
30 changes: 26 additions & 4 deletions clients/web/src/routes/_protected/rooms.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@
import { createFileRoute } from '@tanstack/react-router'
import { GuestPageShell } from '@/components/guests/GuestPageShell'
import { useState } from 'react'
import { PageShell } from '@/components/ui/PageShell'

export const Route = createFileRoute('/_protected/rooms')({
component: RoomsPage,
})

function RoomsPage() {
const [open, setOpen] = useState(false)
return (
<GuestPageShell title="Rooms">
<p className="text-gray-600">Rooms page WIP...</p>
</GuestPageShell>
<PageShell
header={
<div className="flex items-center justify-between h-full">
<span className="text-[2vh] font-medium text-black">Rooms</span>
<button
onClick={() => setOpen(!open)}
className="border border-gray-300 rounded text-sm"
>
Open
</button>
</div>
}
drawerOpen={open}
drawer={
<div>
<p>Drawer content</p>
</div>
}
>
<div>
<p>Main content goes here.</p>
</div>
</PageShell>
)
}
Loading