frontend: add search and mailto
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import Modal from '$lib/components/Modal.svelte';
|
||||
import UserEditForm from '$lib/components/UserEditForm.svelte';
|
||||
import SubscriptionEditForm from '$lib/components/SubscriptionEditForm.svelte';
|
||||
import InputField from '$lib/components/InputField.svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { page } from '$app/stores';
|
||||
import { applyAction, enhance } from '$app/forms';
|
||||
@@ -25,6 +26,59 @@
|
||||
let selectedSubscription = null;
|
||||
let showSubscriptionModal = false;
|
||||
let showUserModal = false;
|
||||
let searchTerm = '';
|
||||
|
||||
$: filteredUsers = searchTerm ? getFilteredUsers() : users;
|
||||
|
||||
function handleMailButtonClick() {
|
||||
const subject = 'Important Announcement';
|
||||
const body = `Hello everyone,\n\nThis is an important message.`;
|
||||
const bccEmails = filteredUsers
|
||||
.map((/** @type{App.Locals['user']}*/ user) => user.email)
|
||||
.join(',');
|
||||
const encodedSubject = encodeURIComponent(subject);
|
||||
const encodedBody = encodeURIComponent(body);
|
||||
const mailtoLink = `mailto:?bcc=${bccEmails}&subject=${encodedSubject}&body=${encodedBody}`;
|
||||
window.location.href = mailtoLink; // Open the mail client
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a set of users depending on the entered search query
|
||||
* @return {App.Locals['user'][]}*/
|
||||
const getFilteredUsers = () => {
|
||||
if (!searchTerm.trim()) return users;
|
||||
|
||||
const term = searchTerm.trim().toLowerCase();
|
||||
|
||||
return users.filter((/** @type{App.Locals['user']}*/ user) => {
|
||||
const basicMatch = [
|
||||
user.first_name?.toLowerCase(),
|
||||
user.last_name?.toLowerCase(),
|
||||
user.email?.toLowerCase(),
|
||||
user.address?.toLowerCase(),
|
||||
user.city?.toLowerCase(),
|
||||
user.dateofbirth?.toLowerCase(),
|
||||
user.phone?.toLowerCase(),
|
||||
user.company?.toLowerCase(),
|
||||
user.licence?.number?.toLowerCase()
|
||||
].some((field) => field?.includes(term));
|
||||
|
||||
const subscriptionMatch = user.membership?.subscription_model?.name
|
||||
?.toLowerCase()
|
||||
.includes(term);
|
||||
|
||||
const licenceCategoryMatch = user.licence?.categories?.some((cat) =>
|
||||
cat.category.toLowerCase().includes(term)
|
||||
);
|
||||
|
||||
const addressMatch = [
|
||||
user.address?.toLowerCase(),
|
||||
user.zip_code?.toLowerCase(),
|
||||
user.city?.toLowerCase()
|
||||
].some((field) => field?.includes(term));
|
||||
return basicMatch || subscriptionMatch || licenceCategoryMatch || addressMatch;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens the edit modal for the selected user.
|
||||
@@ -50,7 +104,7 @@
|
||||
selectedUser = null;
|
||||
selectedSubscription = null;
|
||||
if (form) {
|
||||
form.errors = undefined;
|
||||
form.errors = [];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -117,13 +171,32 @@
|
||||
{#if activeSection === 'users'}
|
||||
<div class="section-header">
|
||||
<h2>{$t('users')}</h2>
|
||||
<button class="btn primary" on:click={() => openEditUserModal(null)}>
|
||||
<i class="fas fa-plus"></i>
|
||||
{$t('add_new')}
|
||||
</button>
|
||||
<div class="title-container">
|
||||
<InputField
|
||||
name="search"
|
||||
placeholder={$t('placeholder.search')}
|
||||
backgroundColor="--base"
|
||||
/>
|
||||
</div>
|
||||
<!-- <input type="text" bind:value={searchTerm} placeholder={$t('placeholder.search')} /> -->
|
||||
<div>
|
||||
<button
|
||||
class="btn primary"
|
||||
aria-label="Mail Users"
|
||||
on:click={() => handleMailButtonClick()}
|
||||
>
|
||||
<i class="fas fa-envelope"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn primary" on:click={() => openEditUserModal(null)}>
|
||||
<i class="fas fa-plus"></i>
|
||||
{$t('add_new')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion">
|
||||
{#each users as user}
|
||||
{#each filteredUsers as user}
|
||||
<details class="accordion-item">
|
||||
<summary class="accordion-header">
|
||||
{user.first_name}
|
||||
@@ -352,6 +425,18 @@
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.title-container {
|
||||
margin: 0 1rem;
|
||||
flex-grow: 1;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -369,7 +454,6 @@
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
min-height: 600px;
|
||||
background: var(--surface0);
|
||||
border-right: 1px solid var(--surface1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user