265 lines
14 KiB
PHP
265 lines
14 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('content')
|
|
@php
|
|
$baseFilters = array_filter([
|
|
'q' => $search,
|
|
'group' => $selectedGroupId ?: null,
|
|
'mobile' => $selectedMobileFilter,
|
|
], fn ($value) => $value !== null && $value !== '');
|
|
@endphp
|
|
|
|
<section class="page-wrap wide">
|
|
<header class="topbar">
|
|
<div class="title">
|
|
<h1>Contacts</h1>
|
|
<p>
|
|
Contacts locaux, groupes et recherche.
|
|
@if ($lastCardDavSyncRun)
|
|
<span class="block sm:inline">CardDAV : {{ $lastCardDavSyncRun->status }} · {{ $lastCardDavSyncRun->started_at?->diffForHumans() }}</span>
|
|
@endif
|
|
</p>
|
|
</div>
|
|
|
|
<div class="actions">
|
|
@if ($cardDavSyncEnabled)
|
|
<form method="POST" action="{{ route('contacts.sync-carddav') }}">
|
|
@csrf
|
|
<button type="submit" class="secondary">
|
|
↻ Synchroniser
|
|
</button>
|
|
</form>
|
|
@endif
|
|
|
|
<a href="{{ route('contacts.create') }}" class="primary">
|
|
+ Contact local
|
|
</a>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="content-grid">
|
|
<div class="stack">
|
|
<form method="GET" action="{{ route('contacts.index') }}" class="panel flush">
|
|
<div class="panel-body">
|
|
<div class="form-grid contact-filters-grid">
|
|
<div class="field">
|
|
<label for="q">Recherche</label>
|
|
<input
|
|
id="q"
|
|
name="q"
|
|
value="{{ $search }}"
|
|
type="search"
|
|
class="input"
|
|
placeholder="Nom, email ou telephone"
|
|
>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label for="group">Groupe</label>
|
|
<select
|
|
id="group"
|
|
name="group"
|
|
class="select"
|
|
>
|
|
<option value="">Tous</option>
|
|
@foreach ($groups as $group)
|
|
<option value="{{ $group->id }}" @selected($selectedGroupId === $group->id)>{{ $group->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label for="mobile">Mobile</label>
|
|
<select id="mobile" name="mobile" class="select">
|
|
<option value="detected" @selected($selectedMobileFilter === 'detected')>Mobile detecte</option>
|
|
<option value="all" @selected($selectedMobileFilter === 'all')>Tous</option>
|
|
<option value="non_mobile" @selected($selectedMobileFilter === 'non_mobile')>Non mobile</option>
|
|
<option value="invalid" @selected($selectedMobileFilter === 'invalid')>Numero invalide</option>
|
|
<option value="missing" @selected($selectedMobileFilter === 'missing')>Sans telephone</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label for="status">Statut</label>
|
|
<select id="status" name="status" class="select">
|
|
<option value="" @selected($selectedStatus === '')>Tous</option>
|
|
<option value="active" @selected($selectedStatus === 'active')>Actif</option>
|
|
<option value="favorite" @selected($selectedStatus === 'favorite')>Favori</option>
|
|
<option value="opt_out" @selected($selectedStatus === 'opt_out')>Refus SMS</option>
|
|
</select>
|
|
</div>
|
|
|
|
<button type="submit" class="secondary">Filtrer</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="panel">
|
|
<div class="panel-header">
|
|
<h2>Liste des contacts</h2>
|
|
<div class="tabs" aria-label="Vue contacts">
|
|
<a class="{{ (! $favoriteOnly && $selectedStatus === '') ? 'active' : '' }}" href="{{ route('contacts.index', $baseFilters) }}">Tous</a>
|
|
<a class="{{ ($favoriteOnly || $selectedStatus === 'favorite') ? 'active' : '' }}" href="{{ route('contacts.index', array_merge($baseFilters, ['status' => 'favorite'])) }}">Favoris</a>
|
|
<a class="{{ $selectedStatus === 'opt_out' ? 'active' : '' }}" href="{{ route('contacts.index', array_merge($baseFilters, ['status' => 'opt_out'])) }}">Refus SMS</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-wrap">
|
|
<table class="data-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Contact</th>
|
|
<th>Telephone</th>
|
|
<th>Groupes</th>
|
|
<th>Statut</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse ($contacts as $contact)
|
|
@php($primaryPhone = $contact->phoneNumbers->firstWhere('is_primary', true) ?? $contact->phoneNumbers->first())
|
|
<tr>
|
|
<td>
|
|
<a href="{{ route('contacts.show', $contact) }}" class="link item-line">
|
|
@if ($contact->is_favorite)
|
|
<span class="favorite-star" aria-label="Favori">★</span>
|
|
@endif
|
|
<span class="truncate">{{ $contact->displayName() }}</span>
|
|
</a>
|
|
<div class="muted truncate">{{ $contact->email ?: $contact->organization ?: ucfirst($contact->source) }}</div>
|
|
</td>
|
|
<td>
|
|
@if ($primaryPhone)
|
|
{{ $primaryPhone->normalized_number ?: $primaryPhone->raw_number }}
|
|
@if (! $primaryPhone->is_valid)
|
|
<div class="muted">Numero invalide</div>
|
|
@elseif (! $primaryPhone->hasDetectedMobileNumber())
|
|
<div class="muted">Non mobile</div>
|
|
@else
|
|
<div class="muted">Mobile detecte</div>
|
|
@endif
|
|
@else
|
|
<span class="muted">Aucun</span>
|
|
@endif
|
|
</td>
|
|
<td>{{ $contact->groups_count }}</td>
|
|
<td>
|
|
<span class="inline-badges">
|
|
@if ($contact->is_favorite)
|
|
<span class="badge pending">Favori</span>
|
|
@endif
|
|
@if ($contact->sms_opt_out)
|
|
<span class="badge error">Refus SMS</span>
|
|
@endif
|
|
@if (! $contact->is_favorite && ! $contact->sms_opt_out)
|
|
<span class="badge">Actif</span>
|
|
@endif
|
|
</span>
|
|
<form method="POST" action="{{ route('contacts.favorite', $contact) }}" class="mt-sm">
|
|
@csrf
|
|
@method('PATCH')
|
|
<input type="hidden" name="is_favorite" value="{{ $contact->is_favorite ? '0' : '1' }}">
|
|
<button type="submit" class="secondary">
|
|
{{ $contact->is_favorite ? 'Retirer favori' : 'Favori' }}
|
|
</button>
|
|
</form>
|
|
<form method="POST" action="{{ route('contacts.opt-out', $contact) }}" class="mt-sm">
|
|
@csrf
|
|
@method('PATCH')
|
|
<input type="hidden" name="sms_opt_out" value="{{ $contact->sms_opt_out ? '0' : '1' }}">
|
|
<button type="submit" class="secondary">
|
|
{{ $contact->sms_opt_out ? 'Retirer Refus SMS' : 'Refus SMS' }}
|
|
</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="4" class="empty-state">Aucun contact trouve.</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{{ $contacts->links() }}
|
|
</div>
|
|
|
|
<aside class="stack">
|
|
<form method="POST" action="{{ route('contact-groups.store') }}" class="panel">
|
|
@csrf
|
|
|
|
<div class="panel-header">
|
|
<h2>Nouveau groupe</h2>
|
|
</div>
|
|
|
|
<div class="panel-body stack-sm">
|
|
<div class="field">
|
|
<label for="name">Nom</label>
|
|
<input
|
|
id="name"
|
|
name="name"
|
|
value="{{ old('name') }}"
|
|
required
|
|
class="input"
|
|
>
|
|
@error('name')
|
|
<p class="notice error">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label for="description">Description</label>
|
|
<textarea
|
|
id="description"
|
|
name="description"
|
|
rows="3"
|
|
class="textarea"
|
|
>{{ old('description') }}</textarea>
|
|
</div>
|
|
|
|
<label class="field-label inline-badges">
|
|
<input name="is_favorite" type="checkbox" value="1">
|
|
Favori
|
|
</label>
|
|
|
|
<button type="submit" class="primary">
|
|
Creer le groupe
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="panel">
|
|
<div class="panel-header">
|
|
<h2>Groupes</h2>
|
|
</div>
|
|
|
|
<div class="panel-body stack-sm">
|
|
@forelse ($groups as $group)
|
|
<div class="summary-row {{ $group->is_favorite ? 'favorite-row' : '' }}">
|
|
<a href="{{ route('contacts.index', ['group' => $group->id]) }}" class="link truncate flex-fill">
|
|
@if ($group->is_favorite)
|
|
<span class="favorite-star" aria-label="Favori">★</span>
|
|
@endif
|
|
{{ $group->name }}
|
|
</a>
|
|
<span class="pill">{{ $group->contacts_count }}</span>
|
|
|
|
@if ($group->source === 'local')
|
|
<a href="{{ route('contact-groups.edit', $group) }}" class="secondary">
|
|
Modifier
|
|
</a>
|
|
@else
|
|
<span class="pill warn">{{ ucfirst($group->source) }}</span>
|
|
@endif
|
|
</div>
|
|
@empty
|
|
<p class="muted">Aucun groupe.</p>
|
|
@endforelse
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
</section>
|
|
@endsection
|