Fix modal chat toggling issue

This commit is contained in:
fatihalp 2026-03-08 22:29:11 +03:00
parent 4e0ed5ca36
commit 4f0b6d0ef2
7 changed files with 63 additions and 85 deletions

View File

@ -5,3 +5,4 @@ Act as a Senior Laravel & FilamentPHP Architect. Refactor the attached code as a
4. Database: Consolidate migrations into a single file per table or topic (e.g., users, cache, jobs) to reduce the overall number of migration files. 4. Database: Consolidate migrations into a single file per table or topic (e.g., users, cache, jobs) to reduce the overall number of migration files.
5. Modularity: Use the `laravel-modules` package to encapsulate all features, routing, and Filament resources strictly inside their respective modules. 5. Modularity: Use the `laravel-modules` package to encapsulate all features, routing, and Filament resources strictly inside their respective modules.
6. Frontend: Optimize and reduce the CSS footprint while maintaining the exact same visual output. 6. Frontend: Optimize and reduce the CSS footprint while maintaining the exact same visual output.
7. Tooling: Use Laravel Boost as the default framework intelligence layer. Search Laravel Boost documentation before framework-level changes and prefer Boost MCP tools for artisan, browser logs, database inspection, and debugging.

View File

@ -5,3 +5,4 @@ Act as a Senior Laravel & FilamentPHP Architect. Refactor the attached code as a
4. Database: Consolidate migrations into a single file per table or topic (e.g., users, cache, jobs) to reduce the overall number of migration files. 4. Database: Consolidate migrations into a single file per table or topic (e.g., users, cache, jobs) to reduce the overall number of migration files.
5. Modularity: Use the `laravel-modules` package to encapsulate all features, routing, and Filament resources strictly inside their respective modules. 5. Modularity: Use the `laravel-modules` package to encapsulate all features, routing, and Filament resources strictly inside their respective modules.
6. Frontend: Optimize and reduce the CSS footprint while maintaining the exact same visual output. 6. Frontend: Optimize and reduce the CSS footprint while maintaining the exact same visual output.
7. Tooling: Use Laravel Boost as the default framework intelligence layer. Search Laravel Boost documentation before framework-level changes and prefer Boost MCP tools for artisan, browser logs, database inspection, and debugging.

View File

@ -1,3 +1,14 @@
Act as a Senior Laravel & FilamentPHP Architect. Refactor the attached code as a greenfield project adhering to the following strict constraints:
1. Architecture: Enforce strict SOLID principles, prioritize brevity, and completely ignore backward compatibility.
2. Cleanup: Remove all legacy code, comments, tests, and PHPDocs.
3. Refactoring: Move all database logic into Models and extract repetitive Filament code into dedicated Helper classes. Identify and fix any existing logical errors.
4. Database: Consolidate migrations into a single file per table or topic (e.g., users, cache, jobs) to reduce the overall number of migration files.
5. Modularity: Use the `laravel-modules` package to encapsulate all features, routing, and Filament resources strictly inside their respective modules.
6. Frontend: Optimize and reduce the CSS footprint while maintaining the exact same visual output.
7. Tooling: Use Laravel Boost as the default framework intelligence layer. Search Laravel Boost documentation before framework-level changes and prefer Boost MCP tools for artisan, browser logs, database inspection, and debugging.
===
<laravel-boost-guidelines> <laravel-boost-guidelines>
=== foundation rules === === foundation rules ===

View File

@ -114,10 +114,13 @@ const appendInlineChatMessage = (thread, emptyState, message) => {
const initInlineListingChat = () => { const initInlineListingChat = () => {
const root = document.querySelector('[data-inline-chat]'); const root = document.querySelector('[data-inline-chat]');
if (!root) { if (!root || root.dataset.chatBound === '1') {
return; return;
} }
root.dataset.chatBound = '1';
const launcher = root.querySelector('[data-inline-chat-launcher]');
const panel = root.querySelector('[data-inline-chat-panel]'); const panel = root.querySelector('[data-inline-chat-panel]');
const thread = root.querySelector('[data-inline-chat-thread]'); const thread = root.querySelector('[data-inline-chat-thread]');
const emptyState = root.querySelector('[data-inline-chat-empty]'); const emptyState = root.querySelector('[data-inline-chat-empty]');
@ -148,9 +151,8 @@ const initInlineListingChat = () => {
root.classList.toggle('is-collapsed', state === 'collapsed'); root.classList.toggle('is-collapsed', state === 'collapsed');
root.classList.toggle('is-sending', state === 'sending'); root.classList.toggle('is-sending', state === 'sending');
if (panel) { launcher?.toggleAttribute('hidden', isOpen);
panel.hidden = !isOpen; panel?.toggleAttribute('hidden', !isOpen);
}
if (isOpen) { if (isOpen) {
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
@ -201,22 +203,47 @@ const initInlineListingChat = () => {
updateHeaderInboxBadge(payload?.counts?.unread_messages_total ?? 0); updateHeaderInboxBadge(payload?.counts?.unread_messages_total ?? 0);
}; };
document.querySelectorAll('[data-inline-chat-open]').forEach((button) => { const openChat = async (event) => {
button.addEventListener('click', async () => { event?.preventDefault();
event?.stopPropagation();
if (root.dataset.state === 'open' || root.dataset.state === 'sending') {
return;
}
showError(''); showError('');
setState('open'); setState('open');
await markConversationRead(); await markConversationRead();
}); };
document.querySelectorAll('[data-inline-chat-trigger]').forEach((button) => {
button.addEventListener('click', openChat);
}); });
root.querySelector('[data-inline-chat-close]')?.addEventListener('click', () => { launcher?.addEventListener('click', openChat);
root.querySelector('[data-inline-chat-close]')?.addEventListener('click', (event) => {
event.preventDefault();
event.stopPropagation();
if (root.dataset.state === 'collapsed') {
return;
}
showError('');
setState('collapsed'); setState('collapsed');
}); });
root.addEventListener('click', (event) => {
if (event.target.closest('[data-inline-chat-panel]')) {
event.stopPropagation();
}
});
form?.addEventListener('submit', async (event) => { form?.addEventListener('submit', async (event) => {
event.preventDefault(); event.preventDefault();
event.stopPropagation();
if (!input || !submitButton) { if (!input || !submitButton || root.dataset.state === 'sending') {
return; return;
} }

View File

@ -292,7 +292,7 @@
@if(! $listing->user) @if(! $listing->user)
<button type="button" class="lt-btn" disabled>Unavailable</button> <button type="button" class="lt-btn" disabled>Unavailable</button>
@elseif($canStartConversation) @elseif($canStartConversation)
<button type="button" class="lt-btn" data-inline-chat-open>Message</button> <button type="button" class="lt-btn" data-inline-chat-trigger>Message</button>
@elseif($isOwnListing) @elseif($isOwnListing)
<button type="button" class="lt-btn" disabled>Your listing</button> <button type="button" class="lt-btn" disabled>Your listing</button>
@else @else
@ -369,7 +369,7 @@
@if(! $listing->user) @if(! $listing->user)
<button type="button" class="lt-btn" disabled>Unavailable</button> <button type="button" class="lt-btn" disabled>Unavailable</button>
@elseif($canStartConversation) @elseif($canStartConversation)
<button type="button" class="lt-btn" data-inline-chat-open>Message</button> <button type="button" class="lt-btn" data-inline-chat-trigger>Message</button>
@elseif($isOwnListing) @elseif($isOwnListing)
<button type="button" class="lt-btn" disabled>Your listing</button> <button type="button" class="lt-btn" disabled>Your listing</button>
@else @else
@ -412,7 +412,7 @@
data-read-url="{{ $chatReadUrl }}" data-read-url="{{ $chatReadUrl }}"
data-read-url-template="{{ route('conversations.read', ['conversation' => '__CONVERSATION__']) }}" data-read-url-template="{{ route('conversations.read', ['conversation' => '__CONVERSATION__']) }}"
> >
<button type="button" class="lt-chat-launcher" data-inline-chat-open aria-label="Open chat"> <button type="button" class="lt-chat-launcher" data-inline-chat-launcher aria-label="Open chat">
<span class="lt-chat-launcher-copy"> <span class="lt-chat-launcher-copy">
<span class="lt-chat-launcher-kicker">Chat</span> <span class="lt-chat-launcher-kicker">Chat</span>
<span class="lt-chat-launcher-name">{{ $sellerName }}</span> <span class="lt-chat-launcher-name">{{ $sellerName }}</span>

View File

@ -15,13 +15,6 @@ A modern classified ads platform built with Laravel 12, FilamentPHP v5, and Lara
- 🐳 **Docker Ready** — One-command production and development setup - 🐳 **Docker Ready** — One-command production and development setup
- ☁️ **GitHub Codespaces** — Zero-config cloud development - ☁️ **GitHub Codespaces** — Zero-config cloud development
## AI Custom Instructions
Project-level custom instruction set files are available at:
- `.chatgpt/CUSTOM_INSTRUCTIONS.md` (ChatGPT)
- `.codex/CUSTOM_INSTRUCTIONS.md` (Codex)
- `.gemini/CUSTOM_INSTRUCTIONS.md` (Google Gemini / Antigravity)
## Tech Stack ## Tech Stack
@ -32,7 +25,7 @@ Project-level custom instruction set files are available at:
| Modules | nWidart/laravel-modules v11 | | Modules | nWidart/laravel-modules v11 |
| Auth/Roles | Spatie Laravel Permission | | Auth/Roles | Spatie Laravel Permission |
| Frontend | Blade + TailwindCSS + Vite | | Frontend | Blade + TailwindCSS + Vite |
| Database | PostgreSQL (required for demo mode), SQLite for minimal local dev | | Database | PostgreSQL (required for demo mode) |
| Cache/Queue | Database or Redis | | Cache/Queue | Database or Redis |
## Quick Start (Docker) ## Quick Start (Docker)
@ -147,50 +140,6 @@ php artisan demo:prepare
php artisan demo:cleanup php artisan demo:cleanup
``` ```
### Notes
- `php artisan db:seed` only injects demo-heavy listings, favorites, inbox threads, and demo users when demo mode is enabled.
- Public infrastructure tables such as sessions, cache, jobs, and failed jobs remain on the public schema even while visitor requests are switched into demo schemas.
---
## Architecture
### Module Structure
```
Modules/
├── Admin/ # FilamentPHP Admin Panel
│ ├── Filament/
│ │ └── Resources/ # CRUD resources (User, Category, Listing, Location)
│ └── Providers/
│ ├── AdminServiceProvider.php
│ └── AdminPanelProvider.php
├── Category/ # Category management
│ ├── Models/Category.php
│ ├── Http/Controllers/
│ ├── database/migrations/
│ └── database/seeders/
├── Listing/ # Listing management
│ ├── Models/Listing.php
│ ├── Http/Controllers/
│ ├── database/migrations/
│ └── database/seeders/
├── Location/ # Countries & Cities
│ ├── Models/{Country,City,District}.php
│ ├── database/migrations/
│ └── database/seeders/
└── User/ # Users, auth, profile, and account flows
├── App/Http/Controllers/
├── App/Models/
├── Database/Seeders/
└── database/migrations/
```
### Panels ### Panels
| Panel | URL | Access | | Panel | URL | Access |
@ -298,19 +247,3 @@ php artisan route:cache
php artisan view:cache php artisan view:cache
php artisan storage:link php artisan storage:link
``` ```
---
## Contributing
1. Fork the repository
2. Create a feature branch: `git checkout -b feature/your-feature`
3. Commit your changes: `git commit -m 'Add your feature'`
4. Push to the branch: `git push origin feature/your-feature`
5. Open a Pull Request
---
## License
MIT License. See [LICENSE](LICENSE) for details.

View File

@ -1478,6 +1478,11 @@ summary::-webkit-details-marker {
gap: 12px; gap: 12px;
} }
.lt-chat-launcher[hidden],
.lt-chat-panel[hidden] {
display: none !important;
}
.lt-chat-launcher { .lt-chat-launcher {
min-width: 176px; min-width: 176px;
max-width: min(260px, calc(100vw - 28px)); max-width: min(260px, calc(100vw - 28px));