mirror of
https://codeberg.org/JasterV/spazio-solazzo.git
synced 2026-04-26 18:20:03 +00:00
refactor: create a reusable component for dashboard tool cards
This commit is contained in:
parent
ee1232d829
commit
3239ef0bd9
5 changed files with 93 additions and 118 deletions
|
|
@ -0,0 +1,65 @@
|
|||
defmodule SpazioSolazzoWeb.AdminDashboardComponents do
|
||||
@moduledoc """
|
||||
Reusable components for the booking flow.
|
||||
"""
|
||||
use Phoenix.Component
|
||||
|
||||
import SpazioSolazzoWeb.CoreComponents, only: [icon: 1]
|
||||
|
||||
attr :title, :string, required: true
|
||||
attr :description, :string, required: true
|
||||
attr :color, :atom, values: [:primary, :secondary], required: true
|
||||
attr :icon, :string, required: true
|
||||
attr :navigate, :string, required: true
|
||||
|
||||
@doc """
|
||||
Renders a tool card to be displayed in the admin dashboard
|
||||
"""
|
||||
def tool_card(assigns) do
|
||||
~H"""
|
||||
<.link
|
||||
navigate={@navigate}
|
||||
class={"group bg-white dark:bg-slate-800 rounded-3xl p-8 border-2 border-slate-200 dark:border-slate-700 shadow-xl shadow-slate-200/50 dark:shadow-none #{container_color_class(@color)} transition-all duration-300 hover:scale-[1.02]"}
|
||||
>
|
||||
<div class="flex flex-col h-full">
|
||||
<div class="flex items-start justify-between mb-6">
|
||||
<div class={"size-16 rounded-2xl #{icon_color_class(@color)} flex items-center justify-center group-hover:scale-110 transition-transform duration-300"}>
|
||||
<.icon name={@icon} class="w-8 h-8" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class={"text-2xl font-bold text-slate-900 dark:text-white mb-3 #{title_color_class(@color)} transition-colors"}>
|
||||
{@title}
|
||||
</h2>
|
||||
|
||||
<p class="text-slate-600 dark:text-slate-400 mb-6 flex-grow">
|
||||
{@description}
|
||||
</p>
|
||||
|
||||
<div class={"flex items-center #{tooltip_color_class(@color)} font-semibold group-hover:gap-3 transition-all"}>
|
||||
<span>Open Tool</span>
|
||||
<.icon
|
||||
name="hero-arrow-right"
|
||||
class="w-5 h-5 group-hover:translate-x-1 transition-transform"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</.link>
|
||||
"""
|
||||
end
|
||||
|
||||
defp container_color_class(:primary), do: "hover:border-primary dark:hover:border-primary"
|
||||
defp container_color_class(:secondary), do: "hover:border-sky-500 dark:hover:border-sky-400"
|
||||
|
||||
defp icon_color_class(:primary),
|
||||
do: "bg-amber-100 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400"
|
||||
|
||||
defp icon_color_class(:secondary),
|
||||
do: "bg-sky-100 dark:bg-sky-900/30 text-sky-600 dark:text-sky-400 "
|
||||
|
||||
defp title_color_class(:primary), do: "group-hover:text-primary dark:group-hover:text-primary"
|
||||
defp title_color_class(:secondary), do: "group-hover:text-sky-500 dark:group-hover:text-sky-400"
|
||||
|
||||
defp tooltip_color_class(:primary), do: "text-primary dark:text-primary-hover"
|
||||
defp tooltip_color_class(:secondary), do: "text-sky-500 dark:text-sky-400"
|
||||
end
|
||||
|
|
@ -1,15 +1,10 @@
|
|||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<main class="flex-grow px-4 py-8 md:px-8">
|
||||
<div class="max-w-6xl mx-auto flex flex-col gap-8">
|
||||
<%!-- Header with back button --%>
|
||||
<div class="flex items-center gap-4">
|
||||
<.link
|
||||
navigate="/admin/dashboard"
|
||||
class="inline-flex items-center gap-2 text-sm font-medium text-slate-500 hover:text-primary dark:text-slate-400 dark:hover:text-primary transition-colors"
|
||||
>
|
||||
<.icon name="hero-arrow-left" class="w-5 h-5" /> Back to Dashboard
|
||||
</.link>
|
||||
</div>
|
||||
<.back_to_link
|
||||
navigate={~p"/admin/dashboard"}
|
||||
value="Back to Dashboard"
|
||||
/>
|
||||
|
||||
<%!-- Title and stats --%>
|
||||
<div class="flex flex-col md:flex-row md:items-end justify-between gap-4">
|
||||
|
|
|
|||
|
|
@ -5,16 +5,9 @@ defmodule SpazioSolazzoWeb.Admin.DashboardLive do
|
|||
|
||||
use SpazioSolazzoWeb, :live_view
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
# Get pending requests count directly from database (no data loaded)
|
||||
{:ok, pending_count} =
|
||||
Ash.count(SpazioSolazzo.BookingSystem.Booking,
|
||||
query: [filter: [state: :requested]]
|
||||
)
|
||||
import SpazioSolazzoWeb.AdminDashboardComponents
|
||||
|
||||
{:ok,
|
||||
assign(socket,
|
||||
pending_requests_count: pending_count
|
||||
)}
|
||||
def mount(_params, _session, socket) do
|
||||
{:ok, socket}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,97 +6,26 @@
|
|||
Admin Dashboard
|
||||
</h1>
|
||||
<p class="text-lg text-slate-600 dark:text-slate-400 max-w-2xl mx-auto">
|
||||
Welcome to Spazio Solazzo management center. Choose a tool below to get started.
|
||||
Welcome to Spazio Solazzo management center.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<%!-- Booking Management Tool Card --%>
|
||||
<.link
|
||||
navigate="/admin/bookings"
|
||||
class="group bg-white dark:bg-slate-800 rounded-3xl p-8 border-2 border-slate-200 dark:border-slate-700 shadow-xl shadow-slate-200/50 dark:shadow-none hover:border-primary dark:hover:border-primary transition-all duration-300 hover:scale-[1.02]"
|
||||
>
|
||||
<div class="flex flex-col h-full">
|
||||
<div class="flex items-start justify-between mb-6">
|
||||
<div class="size-16 rounded-2xl bg-amber-100 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400 flex items-center justify-center group-hover:scale-110 transition-transform duration-300">
|
||||
<.icon name="hero-clipboard-document-list" class="w-8 h-8" />
|
||||
</div>
|
||||
<%= if @pending_requests_count > 0 do %>
|
||||
<span class="bg-amber-100 dark:bg-amber-900/40 text-amber-800 dark:text-amber-200 text-xs font-bold px-3 py-1 rounded-full flex items-center gap-1">
|
||||
<.icon name="hero-clock" class="w-3.5 h-3.5" />
|
||||
{@pending_requests_count} pending
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<.tool_card
|
||||
title="Booking Management"
|
||||
description="Review and manage pending booking requests. Approve or reject reservations and view booking history."
|
||||
color={:primary}
|
||||
icon="hero-clipboard-document-list"
|
||||
navigate={~p"/admin/bookings"}
|
||||
/>
|
||||
|
||||
<h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-3 group-hover:text-primary dark:group-hover:text-primary transition-colors">
|
||||
Booking Management
|
||||
</h2>
|
||||
|
||||
<p class="text-slate-600 dark:text-slate-400 mb-6 flex-grow">
|
||||
Review and manage pending booking requests. Approve or reject reservations and view booking history.
|
||||
</p>
|
||||
|
||||
<div class="flex items-center text-primary dark:text-primary-hover font-semibold group-hover:gap-3 transition-all">
|
||||
<span>Open Tool</span>
|
||||
<.icon
|
||||
name="hero-arrow-right"
|
||||
class="w-5 h-5 group-hover:translate-x-1 transition-transform"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</.link>
|
||||
|
||||
<%!-- Walk-in Booking Tool Card --%>
|
||||
<.link
|
||||
navigate="/admin/walk-in"
|
||||
class="group bg-white dark:bg-slate-800 rounded-3xl p-8 border-2 border-slate-200 dark:border-slate-700 shadow-xl shadow-slate-200/50 dark:shadow-none hover:border-sky-500 dark:hover:border-sky-400 transition-all duration-300 hover:scale-[1.02]"
|
||||
>
|
||||
<div class="flex flex-col h-full">
|
||||
<div class="flex items-start justify-between mb-6">
|
||||
<div class="size-16 rounded-2xl bg-sky-100 dark:bg-sky-900/30 text-sky-600 dark:text-sky-400 flex items-center justify-center group-hover:scale-110 transition-transform duration-300">
|
||||
<.icon name="hero-user-plus" class="w-8 h-8" />
|
||||
</div>
|
||||
<span class="bg-sky-100 dark:bg-sky-900/40 text-sky-800 dark:text-sky-200 text-xs font-bold px-3 py-1 rounded-full flex items-center gap-1">
|
||||
<.icon name="hero-building-office-2" class="w-3.5 h-3.5" /> Coworking Only
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-3 group-hover:text-sky-500 dark:group-hover:text-sky-400 transition-colors">
|
||||
Walk-in Booking
|
||||
</h2>
|
||||
|
||||
<p class="text-slate-600 dark:text-slate-400 mb-6 flex-grow">
|
||||
Create instant bookings for walk-in customers at the coworking space. View real-time availability calendar.
|
||||
</p>
|
||||
|
||||
<div class="flex items-center text-sky-500 dark:text-sky-400 font-semibold group-hover:gap-3 transition-all">
|
||||
<span>Open Tool</span>
|
||||
<.icon
|
||||
name="hero-arrow-right"
|
||||
class="w-5 h-5 group-hover:translate-x-1 transition-transform"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</.link>
|
||||
</div>
|
||||
|
||||
<div class="mt-12 p-6 bg-slate-50 dark:bg-slate-800/50 rounded-2xl border border-slate-200 dark:border-slate-700">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="shrink-0 text-slate-400 dark:text-slate-500">
|
||||
<.icon name="hero-information-circle" class="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-bold text-slate-900 dark:text-white mb-1">
|
||||
Quick Tips
|
||||
</h3>
|
||||
<ul class="text-sm text-slate-600 dark:text-slate-400 space-y-1">
|
||||
<li>• Booking requests require approval before confirmation</li>
|
||||
<li>• Walk-in bookings are instantly approved for coworking space</li>
|
||||
<li>• All bookings are paid upon customer arrival at reception</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<.tool_card
|
||||
title="Arcipelago Walk-in Booking"
|
||||
description="Create instant bookings for walk-in customers at the coworking space."
|
||||
color={:secondary}
|
||||
icon="hero-building-office-2"
|
||||
navigate={~p"/admin/walk-in"}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,10 @@
|
|||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<main class="flex-1">
|
||||
<section class="mx-auto max-w-[1000px] px-6 py-10">
|
||||
<%!-- Header with back button --%>
|
||||
<div class="mb-6">
|
||||
<.link
|
||||
navigate="/admin/dashboard"
|
||||
class="inline-flex items-center gap-2 text-sm font-medium text-slate-500 hover:text-primary dark:text-slate-400 dark:hover:text-primary transition-colors"
|
||||
>
|
||||
<.icon name="hero-arrow-left" class="w-5 h-5" /> Back to Dashboard
|
||||
</.link>
|
||||
</div>
|
||||
<.back_to_link
|
||||
navigate={~p"/admin/dashboard"}
|
||||
value="Back to Dashboard"
|
||||
/>
|
||||
|
||||
<%!-- Title --%>
|
||||
<div class="mb-10 flex flex-col items-center md:items-start text-center md:text-left">
|
||||
|
|
@ -22,7 +17,7 @@
|
|||
</div>
|
||||
|
||||
<div class="space-y-8">
|
||||
<%!-- Step 1: Date & Time --%>
|
||||
<%!-- Date & Time --%>
|
||||
<article class="bg-white dark:bg-slate-800 rounded-3xl p-6 md:p-8 border border-slate-200 dark:border-slate-700 shadow-xl shadow-slate-200/50 dark:shadow-none transition-all hover:border-primary/50 dark:hover:border-primary/50 group">
|
||||
<header class="flex flex-col md:flex-row md:items-center gap-4 mb-8 pb-6 border-b border-slate-100 dark:border-slate-700/50">
|
||||
<div class="size-12 rounded-2xl bg-primary text-white flex items-center justify-center text-xl font-bold shadow-lg shadow-primary/30 group-hover:scale-110 transition-transform duration-300">
|
||||
|
|
@ -171,7 +166,7 @@
|
|||
</div>
|
||||
</article>
|
||||
|
||||
<%!-- Step 2: Customer Details --%>
|
||||
<%!-- Customer Details --%>
|
||||
<article class="bg-white dark:bg-slate-800 rounded-3xl p-6 md:p-8 border border-slate-200 dark:border-slate-700 shadow-xl shadow-slate-200/50 dark:shadow-none transition-all hover:border-primary/50 dark:hover:border-primary/50 group">
|
||||
<header class="flex flex-col md:flex-row md:items-center gap-4 mb-8 pb-6 border-b border-slate-100 dark:border-slate-700/50">
|
||||
<div class="size-12 rounded-2xl bg-primary text-white flex items-center justify-center text-xl font-bold shadow-lg shadow-primary/30 group-hover:scale-110 transition-transform duration-300">
|
||||
|
|
@ -234,7 +229,6 @@
|
|||
</.form>
|
||||
</article>
|
||||
|
||||
<%!-- Submit button --%>
|
||||
<div class="flex justify-center pt-4">
|
||||
<.button
|
||||
type="submit"
|
||||
|
|
@ -242,7 +236,6 @@
|
|||
class="w-full sm:w-auto flex items-center justify-center gap-2 overflow-hidden rounded-xl h-12 px-10 bg-primary hover:bg-primary/90 transition-colors text-white text-base font-bold shadow-lg shadow-primary/30"
|
||||
>
|
||||
<span>Create Booking</span>
|
||||
<.icon name="hero-check" class="w-5 h-5" />
|
||||
</.button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue