chore(UI Improvements): made all pages in broker panel full width

toasts timer increased to 5s.
Add animation to the toast
Add toast for like and favorite actions
fixed the deal card design
added a opening animation to modal
This commit is contained in:
kusowl 2026-01-19 14:11:52 +05:30
parent 89271220fa
commit 688fd02e26
21 changed files with 91 additions and 45 deletions

View File

@ -33,7 +33,7 @@ public function togglesState(Deal $deal, InteractionType $type)
$message = ''; $message = '';
if ($existingInteraction) { if ($existingInteraction) {
$existingInteraction->delete(); $existingInteraction->delete();
$message = "{$type->value} removed from deal"; $message = ucfirst($type->value).' removed from deal';
} else { } else {
$data = [ $data = [
'type' => $type, 'type' => $type,
@ -44,7 +44,7 @@ public function togglesState(Deal $deal, InteractionType $type)
$deal->interactions()->create($data); $deal->interactions()->create($data);
Interaction::reguard(); Interaction::reguard();
$message = "{$type->value} added to deal"; $message = ucfirst($type->value).' added to deal';
} }
return response()->json(['message' => $message]); return response()->json(['message' => $message]);

View File

@ -33,3 +33,27 @@ @layer base{
.preload * { .preload * {
transition: none !important; transition: none !important;
} }
@keyframes appear {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes disappear {
from {
display: block;
opacity: 1;
}
to {
display: none;
opacity: 0;
}
}
dialog{
animation: disappear 300ms ease-in-out;
}
dialog[open]{
animation: appear 300ms ease-in-out;
}

View File

@ -1,3 +1,5 @@
import {showToast} from "./toast.js";
async function like(button, id) { async function like(button, id) {
// Instant feedback for user // Instant feedback for user
let likeBtns = button.querySelectorAll('.like'); let likeBtns = button.querySelectorAll('.like');
@ -12,10 +14,16 @@ async function like(button, id) {
let response = await axios.post('/like/' + id); let response = await axios.post('/like/' + id);
if (response.status !== 200) { if (response.status !== 200) {
showToast(response.data.message)
// Revert the ui // Revert the ui
toggleHidden(likeBtns); toggleHidden(likeBtns);
} }
else{
showToast(response.data.message)
}
} catch (e) { } catch (e) {
showToast(e.response.data.message)
toggleHidden(likeBtns); toggleHidden(likeBtns);
console.error(e); console.error(e);
} }
@ -30,10 +38,14 @@ async function favorite(e, id) {
let response = await axios.post('/favorite/' + id); let response = await axios.post('/favorite/' + id);
if (response.status !== 200) { if (response.status !== 200) {
showToast(response.data.message)
// Revert the ui // Revert the ui
toggleHidden(favoriteBtns); toggleHidden(favoriteBtns);
}else{
showToast(response.data.message);
} }
} catch (e) { } catch (e) {
showToast(e.response.data.message)
toggleHidden(favoriteBtns); toggleHidden(favoriteBtns);
console.error(e); console.error(e);
} }

View File

@ -2,14 +2,16 @@ const toast = document.querySelector('.toast');
const toastBtn = document.querySelector('#toast-btn'); const toastBtn = document.querySelector('#toast-btn');
let toastMessage = toast.querySelector('#toast-message'); let toastMessage = toast.querySelector('#toast-message');
export function showToast(message) { export function showToast(message) {
toast.classList.toggle('hidden') toast.classList.remove('translate-x-[100vw]');
toast.classList.add('translate-x-0');
toastMessage.textContent = message; toastMessage.textContent = message;
setTimeout(() => { setTimeout(() => {
toast.classList.toggle('hidden'); hideToast();
}, 3000) }, 5000)
} }
function hideToast() { function hideToast() {
toast.classList.toggle('hidden') toast.classList.remove('translate-x-0');
toast.classList.add('translate-x-[100vw]');
} }
document.hideToast = hideToast; document.hideToast = hideToast;
document.showToast = showToast; document.showToast = showToast;

View File

@ -4,7 +4,7 @@
<x-dashboard.broker.sidebar class="hidden shrink-0 md:w-50 lg:w-60 md:block md:h-screen" <x-dashboard.broker.sidebar class="hidden shrink-0 md:w-50 lg:w-60 md:block md:h-screen"
active-class="bg-linear-120 from-[#1a55ed] to-[#9b1cff] text-white"/> active-class="bg-linear-120 from-[#1a55ed] to-[#9b1cff] text-white"/>
<section <section
class=" flex flex-col space-y-8 bg-[#F9FAFB] overflow-y-auto h-screen w-full"> class=" flex flex-col space-y-4 md:space-y-8 bg-[#F9FAFB] overflow-y-auto h-screen w-full">
{{$heading ?? ''}} {{$heading ?? ''}}
@ -19,6 +19,7 @@ class=" flex flex-col space-y-8 bg-[#F9FAFB] overflow-y-auto h-screen w-full">
<x-ui.alert variant="error">{{$value}}</x-ui.alert> <x-ui.alert variant="error">{{$value}}</x-ui.alert>
</div> </div>
@endsession @endsession
{{$slot}} {{$slot}}
</section> </section>
</div> </div>

View File

@ -5,10 +5,10 @@
<div class=""> <div class="">
<div class="flex space-x-3 border-b border-b-gray-300 pb-6"> <div class="flex space-x-3 border-b border-b-gray-300 pb-6">
<x-logo/> <x-logo/>
<div class=""> <a href="{{route('home')}}" class="">
<p class="text-2xl font-bold">DealHub</p> <p class="text-2xl font-bold">DealHub</p>
<p class="text-accent-600 text-sm">Broker Panel</p> <p class="text-accent-600 text-sm">Broker Panel</p>
</div> </a>
</div> </div>
<div class="pt-6 flex flex-col space-y-3"> <div class="pt-6 flex flex-col space-y-3">
<x-dashboard.broker.sidebar.item :link="route('broker.dashboard')"> <x-dashboard.broker.sidebar.item :link="route('broker.dashboard')">
@ -37,7 +37,7 @@
<form method="post" action="{{route('logout')}}"> <form method="post" action="{{route('logout')}}">
@csrf @csrf
@method('delete') @method('delete')
<button class="py-3 px-4"> <button class="py-3 px-4 border border-white hover:bg-red-50 hover:border-red-200 rounded-xl w-full mt-4 active:scale-80 cursor-pointer transition-all duration-300 ease-in-out">
<div class="flex space-x-2 items-center text-red-500"> <div class="flex space-x-2 items-center text-red-500">
<x-heroicon-o-arrow-right-start-on-rectangle class="w-6"/> <x-heroicon-o-arrow-right-start-on-rectangle class="w-6"/>
<p>Logout</p> <p>Logout</p>

View File

@ -1,5 +1,5 @@
@props([ 'link' => '']) @props([ 'link' => ''])
@aware(['activeClass' => 'bg-gray-100 text-gray-900']) @aware(['activeClass' => 'bg-gray-100 text-gray-900'])
<a href="{{$link}}" {{$attributes->class(["flex space-x-3 items-center py-3 px-4 rounded-xl", $activeClass => url()->current() == $link])}} > <a href="{{$link}}" {{$attributes->class(["flex space-x-3 items-center py-3 px-4 rounded-xl hover:bg-gray-100 border border-white ease-in-out transition-all duration-300 active:scale-80 hover:border-gray-300", $activeClass => url()->current() == $link])}} >
{{$slot}} {{$slot}}
</a> </a>

View File

@ -1,5 +1,5 @@
@props(['list_count' => 0]) @props(['list_count' => 0])
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 wrapper gap-8"> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 wrapper gap-y-4 gap-x-8">
<x-dashboard.stats-card title="My Listings" :score="$list_count"> <x-dashboard.stats-card title="My Listings" :score="$list_count">
<x-icon-square variant="blue"> <x-icon-square variant="blue">
<x-heroicon-o-document-text class="w-8" /> <x-heroicon-o-document-text class="w-8" />

View File

@ -1,3 +1,3 @@
<div {{$attributes->merge(['class' => 'p-6 border border-gray-200 rounded-xl'])}}> <div {{$attributes->merge(['class' => 'p-4 md:p-6 border border-gray-200 rounded-xl'])}}>
{{$slot}} {{$slot}}
</div> </div>

View File

@ -3,9 +3,9 @@
<div class="flex space-x-6 items-center"> <div class="flex space-x-6 items-center">
@if($backLink !== '') @if($backLink !== '')
<div class=""> <div class="">
<a href="{{$backLink}}"> <x-ui.button-sm :link="$backLink">
<x-heroicon-o-arrow-left class="w-4"/> <x-heroicon-o-arrow-left class="w-4"/>
</a> </x-ui.button-sm>
</div> </div>
@endif @endif
<div class=""> <div class="">

View File

@ -1,5 +1,5 @@
@props(['broker']) @props(['broker'])
<div class="p-4 text-sm"> <div class="p-4 mb-4 text-sm bg-[#f9fafb] border-gray-100 border rounded-xl">
<p class="font-bold mb-2">Broker Contact</p> <p class="font-bold mb-2">Broker Contact</p>
<div class="text-accent-600 space-y-1"> <div class="text-accent-600 space-y-1">
<p>{{$broker->name}}</p> <p>{{$broker->name}}</p>

View File

@ -1,6 +1,6 @@
@props(['deal' => '', 'broker' => '']) @props(['deal' => '', 'broker' => ''])
<x-ui.image-card :image="asset('storage/'.$deal->image)"> <x-ui.image-card class="shadow-lg" :image="asset('storage/'.$deal->image)">
<div class="bg-white pt-8 p-4 h-full space-y-4 flex flex-col justify-between"> <div class="bg-white pt-8 p-4 h-full space-y-2 flex flex-col justify-between">
<div class="flex justify-between"> <div class="flex justify-between">
<x-ui.button-sm variant="neutral"> <x-ui.button-sm variant="neutral">
{{$deal->category->name}} {{$deal->category->name}}

View File

@ -1,12 +1,18 @@
@props(['variant' => '']) @props(['variant' => '', 'link' => ''])
@php @php
$variants = [ $variants = [
'neutral' => 'bg-primary-600 text-white', 'neutral' => 'bg-primary-600 text-white',
'ghost' => 'bg-gray-100 text-black text-sm' 'ghost' => 'bg-gray-100 text-black text-sm',
]; ];
$variantClass = $variants[$variant] ?? ''; $variantClass = $variants[$variant] ?? '';
@endphp @endphp
<button {{$attributes->merge(['class' => "px-2 py-1 text-xs rounded-md font-medium hover:opacity-80 $variantClass"])}}> @if($link !== '')
<a href="{{$link}}" {{$attributes->merge(['class' => "px-2 py-1 text-xs rounded-md font-medium hover:opacity-80 hover: active:scale-80 transition-all duration-300 ease-in-out $variantClass"])}}>
{{$slot}}
</a>
@else
<button {{$attributes->merge(['class' => "px-2 py-1 text-xs rounded-md font-medium hover:opacity-80 hover:scale-110 active:scale-80 transition-all duration-300 ease-in-out $variantClass"])}}>
{{$slot}} {{$slot}}
</button> </button>
@endif

View File

@ -9,7 +9,7 @@
$variantClass = $variants[$variant] ?? ''; $variantClass = $variants[$variant] ?? '';
@endphp @endphp
@if($link !== '') @if($link !== '')
<a {{$attributes->merge(['class' => "block active:scale-90 transition-all duration-200 px-4 py-2 rounded-lg font-medium hover:opacity-80 $variantClass", 'href' => $link])}}> <a {{$attributes->merge(['class' => "block px-4 py-2 rounded-lg font-medium hover:opacity-80 active:scale-80 transition-all ease-in-out duration-300 $variantClass", 'href' => $link])}}>
<div class="flex justify-center items-center space-x-2"> <div class="flex justify-center items-center space-x-2">
@if($icon !=='') @if($icon !=='')
@svg("heroicon-o-$icon", 'w-5 h-5') @svg("heroicon-o-$icon", 'w-5 h-5')
@ -18,7 +18,7 @@
</div> </div>
</a> </a>
@else @else
<button {{$attributes->merge(['class' => "px-4 py-2 rounded-lg font-medium hover:opacity-80 active:scale-90 transition-all duration-200 $variantClass", 'type'=>'submit'])}}> <button {{$attributes->merge(['class' => "px-4 py-2 rounded-lg font-medium hover:opacity-80 active:scale-80 transition-all ease-in-out duration-300 $variantClass", 'type'=>'submit'])}}>
<div class="flex justify-center items-center space-x-2"> <div class="flex justify-center items-center space-x-2">
@if($icon !=='') @if($icon !=='')
@svg("heroicon-o-$icon", 'w-5 h-5') @svg("heroicon-o-$icon", 'w-5 h-5')

View File

@ -1,7 +1,7 @@
@props(['image' => '', 'alt' => '']) @props(['image' => '', 'alt' => ''])
<div class="border border-gray-200 rounded-xl overflow-clip flex flex-col h-full"> <div {{$attributes->merge(['class' => "border border-gray-200 rounded-xl overflow-clip flex flex-col h-full"])}}>
<div class="flex flex-col h-full"> <div class="flex flex-col h-full">
<div class="rounded-t-xl h-40"> <div class="rounded-t-xl h-70">
<img src="{{$image}}" alt="" class="object-cover"> <img src="{{$image}}" alt="" class="object-cover">
</div> </div>
<div class="flex-1"> <div class="flex-1">

View File

@ -1,4 +1,5 @@
<dialog {{$attributes->merge(["class"=>"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white rounded-lg p-4 shadow-lg"])}} > <dialog
{{$attributes->merge(["class"=>"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white rounded-lg p-4 shadow-lg"])}} >
<div> <div>
{{$slot}} {{$slot}}
</div> </div>

View File

@ -1,4 +1,4 @@
<div class="toast hidden fixed top-10 right-5 md:right-10 bg-black text-white rounded-xl shadow-lg p-4 flex space-x-2"> <div class="toast translate-x-[100vw] transition-transform duration-500 ease-in-out fixed top-10 right-5 md:right-10 bg-black text-white rounded-xl shadow-lg p-4 flex space-x-2">
<p id="toast-message" class="max-w-70 wrap-break-word"></p> <p id="toast-message" class="max-w-70 wrap-break-word"></p>
<x-ui.button-sm onclick="hideToast()"> <x-ui.button-sm onclick="hideToast()">
<x-heroicon-o-x-mark class="w-4" /> <x-heroicon-o-x-mark class="w-4" />

View File

@ -8,8 +8,8 @@
/> />
</x-slot:heading> </x-slot:heading>
<div class="flex items-center justify-center mb-8"> <div class="flex items-center justify-center px-4 pb-4 pt-0 md:px-8 md:pb-8">
<x-dashboard.card class="w-11/12 md:w-8/12"> <x-dashboard.card class="w-full">
<h3 class="text-md font-bold">Deal Information</h3> <h3 class="text-md font-bold">Deal Information</h3>
<form method="post" enctype="multipart/form-data" action="{{route('broker.deals.store')}}" <form method="post" enctype="multipart/form-data" action="{{route('broker.deals.store')}}"
class="flex flex-col space-y-8 mt-4"> class="flex flex-col space-y-8 mt-4">
@ -32,10 +32,11 @@ class="flex flex-col space-y-8 mt-4">
description="Add a link to your website, listing page or contact form" description="Add a link to your website, listing page or contact form"
/> />
<div class="grid grid-cols-12 w-full space-x-4"> <div class="grid md:grid-cols-12 w-full gap-4">
<x-ui.button variant="neutral" class="col-span-10">Submit</x-ui.button> <x-ui.button variant="neutral" class="md:col-span-10">Submit</x-ui.button>
<a href="{{route('broker.dashboard')}}" <x-ui.button link="{{route('broker.dashboard')}}" class="border border-accent-600/20 md:col-span-2">
class="ui-btn border border-accent-600/20 col-span-2">Cancel</a> Cancel
</x-ui.button>
</div> </div>
</form> </form>
</x-dashboard.card> </x-dashboard.card>

View File

@ -8,9 +8,8 @@
/> />
</x-slot:heading> </x-slot:heading>
<div class="flex items-center justify-center mt-8"> <div class="flex items-center justify-center px-4 pb-4 pt-0 md:px-8 md:pb-8">
<x-dashboard.card class="w-full">
<x-dashboard.card class="w-11/12 md:w-8/12">
<h3 class="text-md font-bold">Deal Information</h3> <h3 class="text-md font-bold">Deal Information</h3>
<form method="post" enctype="multipart/form-data" action="{{route('broker.deals.update', $deal)}}" <form method="post" enctype="multipart/form-data" action="{{route('broker.deals.update', $deal)}}"
class="flex flex-col space-y-8 mt-4"> class="flex flex-col space-y-8 mt-4">

View File

@ -6,8 +6,8 @@
:back-link="route('broker.profile.show', $profile)" :back-link="route('broker.profile.show', $profile)"
/> />
</x-slot:heading> </x-slot:heading>
<div class="flex items-center justify-center"> <div class="flex items-center justify-center px-4 pb-4 pt-0 md:px-8 md:pb-8">
<x-dashboard.card class="w-8/12"> <x-dashboard.card class="w-full">
<h3 class="text-md font-bold">Profile Information</h3> <h3 class="text-md font-bold">Profile Information</h3>
<form method="post" enctype="multipart/form-data" action="{{route('broker.profile.update', $profile)}}" <form method="post" enctype="multipart/form-data" action="{{route('broker.profile.update', $profile)}}"
class="flex flex-col space-y-8 mt-4"> class="flex flex-col space-y-8 mt-4">
@ -27,10 +27,10 @@ class="flex flex-col space-y-8 mt-4">
<x-ui.input name="location" label="Location" :value="$broker->location" required <x-ui.input name="location" label="Location" :value="$broker->location" required
placeholder="Kolkata, India"/> placeholder="Kolkata, India"/>
<div class="grid grid-cols-12 w-full space-x-4"> <div class="grid md:grid-cols-12 w-full gap-4">
<x-ui.button variant="neutral" class="col-span-10">Update</x-ui.button> <x-ui.button variant="neutral" class="md:col-span-10">Update</x-ui.button>
<x-ui.button :link="route('broker.profile.show', $profile)" <x-ui.button :link="route('broker.profile.show', $profile)"
class=" border border-accent-600/20 col-span-2">Cancel class=" border border-accent-600/20 md:col-span-2">Cancel
</x-ui.button> </x-ui.button>
</div> </div>
</form> </form>

View File

@ -16,8 +16,8 @@ class="border border-accent-600/40">
</x-dashboard.page-heading> </x-dashboard.page-heading>
</x-slot:heading> </x-slot:heading>
<div class="flex items-center justify-center"> <div class="flex items-center justify-center px-4 pb-4 pt-0 md:px-8 md:pb-8">
<div class="flex items-center justify-center w-11/12 md:w-10/12"> <div class="flex items-center justify-center w-full">
<x-dashboard.card class="w-full"> <x-dashboard.card class="w-full">
<div class="grid grid-cols-8 gap-6"> <div class="grid grid-cols-8 gap-6">