Initial commit

This commit is contained in:
Ronald Huynen
2026-03-23 21:37:59 +01:00
commit 2547717edb
2193 changed files with 972171 additions and 0 deletions

View File

@@ -0,0 +1,156 @@
<div class="bg-[var(--wc-light-primary)] dark:bg-[var(--wc-dark-primary)] dark:text-white border border-[var(--wc-light-secondary)] dark:border-[var(--wc-dark-secondary)] overflow-visible">
<header class=" sticky top-0 bg-[var(--wc-light-primary)] dark:bg-[var(--wc-dark-primary)] z-10 p-12 pb-2">
<div class="flex items-center pb-2">
<x-wirechat::actions.close-modal>
<button
class="p-2 ml-0 text-gray-600 hover:bg-[var(--wc-light-secondary)] dark:hover:bg-[var(--wc-dark-secondary)] dark:hover:text-white rounded-full hover:text-gray-800">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class=" w-5 w-5">
<path stroke-linecap="round" stroke-linejoin="round"
d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
</svg>
</button>
</x-wirechat::actions.close-modal>
<h3 class="text-sm mx-auto font-semibold " ><span>{{__('wirechat::chat.group.add_members.heading.label')}} </span> {{$newTotalCount}} / {{$maxGroupMembers}}</h3>
<x-jetstream.button
wire:click="save"
wire:loading.attr="disabled"
wire:target='save'
@disabled(count($selectedMembers)==0)
type="button"
class="text-xs py-1.5 px-3">
{{__('wirechat::chat.group.add_members.actions.save.label')}}
</x-jetstream.button>
</div>
{{-- Member limit error --}}
<div
x-data="{ showError:false }"
x-on:show-member-limit-error.window="
showError=true;
setTimeout(()=>{ showError=false; },1500);
"
class="text-red-500 text-sm mx-auto ">
<span x-transition x-show="showError">
{{__('wirechat::chat.group.add_members.messages.members_limit_error',['count'=>$maxGroupMembers])}}
</span>
</div>
<section class="flex flex-wrap items-center px-0 border-b border-[var(--wc-light-secondary)] dark:border-[var(--wc-dark-secondary)]">
<input type="search" id="users-search-field" wire:model.live.debounce='search' autocomplete="off"
placeholder="{{ __('wirechat::chat.group.add_members.inputs.search.placeholder') }}"
class=" w-full border-0 w-auto dark:bg-none dark:bg-transparent outline-hidden focus:outline-hidden bg-none rounded-lg focus:ring-0 hover:ring-0">
</section>
<section class=" overflow-x-hidden my-2 ">
<ul style="-ms-overflow-style: none;scrollbar-width: none;
"
class="flex w-full overflow-x-auto gap-3">
@if ($selectedMembers)
@foreach ($selectedMembers as $key => $member)
<li class="flex items-center text-nowrap min-w-fit px-2 py-1 text-sm font-medium text-gray-800 bg-[var(--wc-light-secondary)] rounded-sm dark:bg-[var(--wc-dark-secondary)] dark:text-gray-300"
wire:key="selected-member-{{ $member->id }}">
{{ $member->display_name }}
<button type="button"
wire:click="toggleMember('{{ $member->id }}',{{ json_encode(get_class($member)) }})"
class="flex items-center p-1 ms-2 text-sm text-gray-400 bg-transparent rounded-xs hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-gray-300"
aria-label="Remove">
<svg class="w-2 h-2" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg>
<span class="sr-only">Remove badge</span>
</button>
</li>
@endforeach
@endif
</ul>
</section>
</header>
<div class="relative w-full px-12">
{{-- <h5 class="text font-semibold text-gray-800 dark:text-gray-100">Recent Chats</h5> --}}
<section class="my-4">
@if ($users)
<ul class="overflow-auto flex flex-col">
@foreach ($users as $key => $user)
@php
$isAlreadyAParticipant= $user->belongsToConversation($conversation);
@endphp
<li wire:key="users-{{$key}}" class="flex cursor-pointer group gap-2 items-center p-2">
<label
{{-- The wire:click attribute is only rendered if $isAlreadyAParticipant is false. --}}
@if (!$isAlreadyAParticipant)
wire:click="toggleMember('{{ $user->id }}', {{ json_encode(get_class($user)) }})"
@endif
class="flex cursor-pointer gap-2 items-center w-full">
<x-wirechat::avatar src="{{$user->cover_url}}" class="w-10 h-10" />
<div @class(['opacity-70' => $isAlreadyAParticipant, 'flex-1 min-w-0']) >
<p
@class(['transition-all truncate', 'group-hover:underline ' => !$isAlreadyAParticipant])>
{{ $user->display_name }}</p>
<span
@class(['text-gray-600 dark:text-gray-400 text-sm'])>
@if ($isAlreadyAParticipant)
{{__('wirechat::chat.group.add_members.messages.member_already_exists')}}
@else
@php
$location = $user->getLocationFirst();
@endphp
@if ($location && isset($location['name_short']))
{{ $location['name_short'] }}
@endif
@endif
</span>
</div>
<div class="ml-auto">
@if ($selectedMembers->contains(fn($member) => $member->id == $user->id && get_class($member) == get_class($user)) || $isAlreadyAParticipant)
<div class="w-6 h-6 bg-theme-brand rounded flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="w-4 h-4 text-theme-background">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
</div>
@else
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
fill="currentColor" class="bi bi-plus-square-dotted w-6 h-6 text-gray-400"
viewBox="0 0 16 16">
<path
d="M2.5 0q-.25 0-.487.048l.194.98A1.5 1.5 0 0 1 2.5 1h.458V0zm2.292 0h-.917v1h.917zm1.833 0h-.917v1h.917zm1.833 0h-.916v1h.916zm1.834 0h-.917v1h.917zm1.833 0h-.917v1h.917zM13.5 0h-.458v1h.458q.151 0 .293.029l.194-.981A2.5 2.5 0 0 0 13.5 0m2.079 1.11a2.5 2.5 0 0 0-.69-.689l-.556.831q.248.167.415.415l.83-.556zM1.11.421a2.5 2.5 0 0 0-.689.69l.831.556c.11-.164.251-.305.415-.415zM16 2.5q0-.25-.048-.487l-.98.194q.027.141.028.293v.458h1zM.048 2.013A2.5 2.5 0 0 0 0 2.5v.458h1V2.5q0-.151.029-.293zM0 3.875v.917h1v-.917zm16 .917v-.917h-1v.917zM0 5.708v.917h1v-.917zm16 .917v-.917h-1v.917zM0 7.542v.916h1v-.916zm15 .916h1v-.916h-1zM0 9.375v.917h1v-.917zm16 .917v-.917h-1v.917zm-16 .916v.917h1v-.917zm16 .917v-.917h-1v.917zm-16 .917v.458q0 .25.048.487l.98-.194A1.5 1.5 0 0 1 1 13.5v-.458zm16 .458v-.458h-1v.458q0 .151-.029.293l.981.194Q16 13.75 16 13.5M.421 14.89c.183.272.417.506.69.689l.556-.831a1.5 1.5 0 0 1-.415-.415zm14.469.689c.272-.183.506-.417.689-.69l-.831-.556c-.11.164-.251.305-.415.415l.556.83zm-12.877.373Q2.25 16 2.5 16h.458v-1H2.5q-.151 0-.293-.029zM13.5 16q.25 0 .487-.048l-.194-.98A1.5 1.5 0 0 1 13.5 15h-.458v1zm-9.625 0h.917v-1h-.917zm1.833 0h.917v-1h-.917zm1.834-1v1h.916v-1zm1.833 1h.917v-1h-.917zm1.833 0h.917v-1h-.917zM8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3z" />
</svg>
@endif
</div>
</label>
</li>
@endforeach
</ul>
@endif
</section>
</div>
</div>

View File

@@ -0,0 +1,304 @@
<div id="group-info-modal" class="bg-[var(--wc-light-primary)] dark:bg-[var(--wc-dark-primary)] min-h-screen">
@php
$authIsAdminInGroup = $participant?->isAdmin();
$authIsOwner = $participant?->isOwner();
$isGroup = $conversation?->isGroup();
$group = $conversation?->group;
@endphp
<section class="cursor-pointer flex gap-4 z-10 items-center p-5 sticky top-0 bg-[var(--wc-light-primary)] dark:bg-[var(--wc-dark-primary)] ">
<button wire:click="$dispatch('closeChatDrawer')" class="focus:outline-hidden cursor-pointer"> <svg class="w-7 h-7"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg> </button>
<h3>{{__('wirechat::chat.group.info.heading.label')}}</h3>
</section>
{{-- Details --}}
<header>
{{-- Edit group form --}}
@if ($authIsAdminInGroup || $group?->allowsMembersToEditGroupInfo())
<div @dusk="edit_group_information_section" class="flex flex-col items-center gap-5 py-5 px-4 ">
{{-- Avatar --}}
<section class="mx-auto items-center justify-center grid">
<div @dusk="edit_avatar_label" class="relative h-32 w-32 overflow-clip mx-auto rounded-full">
<label wire:target="photo" wire:loading.class="cursor-not-allowed" for="photo"
class=" cursor-pointer w-full h-full">
<x-wirechat::avatar wire:loading.class="cursor-not-allowed" group="{{ $isGroup }}"
:src="$cover_url" class="w-full h-full absolute inset-0" />
</label>
<input accept=".jpg,.jpeg,.png,.webp" wire:loading.attr="disabled" id="photo"
wire:model="photo" dusk="add_photo_field" type="file" hidden>
@if (empty($cover_url))
{{-- penceil --}}
<label wire:target="photo" wire:loading.class="cursor-not-allowed"
wire:loading.class.remove="cursor-pointer" for="photo"
class=" cursor-pointer bottom-0 inset-x-0 bg-gray-500/40 hover:bg-gray-500/80 dark:bg-white/40 dark:hover:bg-gray-700 transition-colors text-gray-600 flex items-center justify-center absolute ">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"
class="size-6 w-5 h-5">
<path
d="M21.731 2.269a2.625 2.625 0 0 0-3.712 0l-1.157 1.157 3.712 3.712 1.157-1.157a2.625 2.625 0 0 0 0-3.712ZM19.513 8.199l-3.712-3.712-12.15 12.15a5.25 5.25 0 0 0-1.32 2.214l-.8 2.685a.75.75 0 0 0 .933.933l2.685-.8a5.25 5.25 0 0 0 2.214-1.32L19.513 8.2Z" />
</svg>
</label>
@else
<button type="button" wire:target="photo" wire:loading.attr="disabled"
class="disabled:cursor-not-allowed bottom-0 inset-x-0 bg-gray-500/40 hover:bg-gray-500/80 m-0 p-0 border-0 dark:bg-white/40 dark:hover:bg-gray-700 transition-colors text-red-800 flex items-center justify-center absolute "
wire:confirm="Are you sure you want to delete photo ?" wire:click="deletePhoto">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" class="size-6 w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round"
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
</svg>
</button>
@endif
</div>
@error('photo')
<span class="text-red-500">{{ $message }}</span>
@enderror
</section>
{{-- Form --}}
<div class="space-y-3 grid overflow-x-hidden">
{{-- Form to update Group name --}}
<form @dusk="edit_group_name_form" wire:submit="updateGroupName" x-data="{ editing: false }"
class=" justify-center flex items-center w-full gap-5 px-5 items-center">
@csrf
{{-- Left side input --}}
<div class=" max-w-[90%] grid h-auto">
<div x-show="!editing">
<h4 dusk="form_group_name_when_not_editing" class="font-medium break-all whitespace-pre-line text-2xl ">{{ $groupName }} </h4>
</div>
<input x-cloak maxlength="110" x-show="editing" id='groupName' type="text"
wire:model='groupName'
class="resize-none text-2xl font-medium border-0 px-0 py-0 py-0 border-b border-[var(--wc-light-border)] dark:border-[var(--wc-dark-border)] bg-inherit dark:text-white outline-hidden w-full focus:outline-hidden focus:ring-0 hover:ring-0">
@error('groupName')
<p class="text-red-500 inline">{{ $message }}</p>
@enderror
</div>
{{-- Right Side --}}
<span class=" items-center">
<button type="button" @click="editing=true" x-show="!editing">
{{-- pencil/edit --}}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"
class="size-6 w-5 h-5">
<path
d="M21.731 2.269a2.625 2.625 0 0 0-3.712 0l-1.157 1.157 3.712 3.712 1.157-1.157a2.625 2.625 0 0 0 0-3.712ZM19.513 8.199l-3.712-3.712-12.15 12.15a5.25 5.25 0 0 0-1.32 2.214l-.8 2.685a.75.75 0 0 0 .933.933l2.685-.8a5.25 5.25 0 0 0 2.214-1.32L19.513 8.2Z" />
</svg>
</button>
<button x-cloak @click="editing=false" x-show="editing">
{{-- check/submit --}}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
fill="currentColor" class="bi bi-check-lg w-5 h-5" viewBox="0 0 16 16">
<path
d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z" />
</svg>
</button>
</span>
</form>
{{-- Members count --}}
<p class="mx-auto"> {{ __('wirechat::chat.group.info.labels.members') }} {{ $totalParticipants }} </p>
</div>
{{-- About --}}
<section class=" px-8 py-5 ">
<div @dusk="edit_description_section" x-data="{ editing: false }" @click.outside="editing=false"
class="grid grid-cols-12 items-center">
{{-- Left side input --}}
<span class="col-span-11">
<div x-show="!editing">
@if (empty($description))
<p class="text-sm" style="color: var(--wirechat-primary-color)">{{ __('wirechat::chat.group.info.labels.add_description') }} </p>
@else
<p class="font-medium break-all whitespace-pre-line ">{{ $description }}
</p>
@endif
</div>
<textarea x-cloak maxlength="501" x-show="editing" id='description' type="text" wire:model.blur='description'
class="resize-none font-medium w-full border-0 px-0 py-0 py-0 border-b border-[var(--wc-light-border)] dark:border-[var(--wc-dark-border)] bg-inherit dark:text-white outline-hidden w-full focus:outline-hidden focus:ring-0 hover:ring-0">
</textarea>
@error('description')
<p class="text-red-500">{{ $message }}</p>
@enderror
</span>
{{-- Right Side --}}
<span class="col-span-1 flex items-center justify-end">
<button @click="editing=true" x-show="!editing">
{{-- pencil/edit --}}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"
class="size-6 w-5 h-5">
<path
d="M21.731 2.269a2.625 2.625 0 0 0-3.712 0l-1.157 1.157 3.712 3.712 1.157-1.157a2.625 2.625 0 0 0 0-3.712ZM19.513 8.199l-3.712-3.712-12.15 12.15a5.25 5.25 0 0 0-1.32 2.214l-.8 2.685a.75.75 0 0 0 .933.933l2.685-.8a5.25 5.25 0 0 0 2.214-1.32L19.513 8.2Z" />
</svg>
</button>
<button x-cloak @click="editing=false" x-show="editing">
{{-- check --}}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
fill="currentColor" class="bi bi-check-lg w-5 h-5" viewBox="0 0 16 16">
<path
d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z" />
</svg>
</button>
</span>
</div>
</section>
</div>
@else
{{-- Plain group information --}}
<div @dusk="non_editable_group_information_section" class="flex flex-col items-center gap-5 py-5 px-4 ">
<x-wirechat::avatar :src="$cover_url" class=" h-32 w-32 mx-auto" />
<h4 dusk="group_name" class="font-medium break-all whitespace-pre-line text-2xl ">{{ $groupName }} </h4>
<p class="mx-auto">{{ __('wirechat::chat.group.info.labels.members') }} {{ $totalParticipants }} </p>
<p class="font-medium break-all whitespace-pre-line ">{{ $description }} </p>
</div>
@endif
</header>
<x-wirechat::divider />
{{-- Disappearing Messages Settings --}}
@if(timebank_config('wirechat.disappearing_messages.enabled', true))
<section class="px-8 py-5">
@livewire('wire-chat.disappearing-messages-settings', ['conversationId' => $conversation->id], key('disappearing-'.$conversation->id))
</section>
<x-wirechat::divider />
@endif
{{-- Members section --}}
<section class="my-4 text-left space-y-3">
{{-- Actiion button to trigger opening members modal --}}
<x-wirechat::actions.open-modal component="wirechat.chat.group.members"
conversation="{{ $conversation?->id }}" widget="{{ $this->isWidget() }}">
{{-- Members count --}}
<button class="cursor-pointer flex w-full justify-between items-center px-8 focus:outline-hidden ">
<span class="text-gray-600 dark:text-gray-300">{{ __('wirechat::chat.group.info.labels.members') }} {{ $totalParticipants }}</span>
{{-- Search icon --}}
<span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="size-6 w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round"
d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
</svg>
</span>
</button>
</x-wirechat::actions.open-modal>
{{-- Add Members --}}
@if ($authIsAdminInGroup || $group?->allowsMembersToAddOthers())
<x-wirechat::actions.open-modal component="wirechat.chat.group.add-members"
conversation="{{ $conversation?->id }}" widget="{{ $this->isWidget() }}">
<button @dusk="open_add_members_modal_button"
class="cursor-pointer w-full py-5 px-8 hover:bg-[var(--wc-light-secondary)] dark:hover:bg-[var(--wc-dark-secondary)] focus:outline-hidden transition flex gap-3 items-center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"
class="size-6 w-5 h-5">
<path
d="M5.25 6.375a4.125 4.125 0 1 1 8.25 0 4.125 4.125 0 0 1-8.25 0ZM2.25 19.125a7.125 7.125 0 0 1 14.25 0v.003l-.001.119a.75.75 0 0 1-.363.63 13.067 13.067 0 0 1-6.761 1.873c-2.472 0-4.786-.684-6.76-1.873a.75.75 0 0 1-.364-.63l-.001-.122ZM18.75 7.5a.75.75 0 0 0-1.5 0v2.25H15a.75.75 0 0 0 0 1.5h2.25v2.25a.75.75 0 0 0 1.5 0v-2.25H21a.75.75 0 0 0 0-1.5h-2.25V7.5Z" />
</svg>
<span>{{ __('wirechat::chat.group.info.actions.add_members.label') }}</span>
</button>
</x-wirechat::actions.open-modal>
@endif
</section>
<x-wirechat::divider />
{{-- Footer section --}}
<footer class="flex flex-col justify-start w-full">
@if ($authIsOwner)
{{-- Delete group --}}
<button wire:confirm="{{ __('wirechat::chat.group.info.actions.delete_group.confirmation_message') }}" wire:click="deleteGroup"
class="cursor-pointer w-full py-5 px-8 hover:bg-[var(--wc-light-secondary)] dark:hover:bg-[var(--wc-dark-secondary)] transition text-start space-y-2 gap-3 text-red-500">
<div class="flex gap-3 items-center ">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="size-6 w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round"
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
</svg>
<span>{{ __('wirechat::chat.group.info.actions.delete_group.label') }}</span>
</div>
<p class="dark:text-white/60 text-sm text-gray-600/80">@lang('wirechat::chat.group.info.actions.delete_group.helper_text')</p>
</button>
{{-- Permissions --}}
<div>
<x-wirechat::actions.open-chat-drawer component='wirechat.chat.group.permissions'
conversation="{{ $conversation?->id }}">
<button
class="cursor-pointer w-full py-5 px-8 hover:bg-[var(--wc-light-secondary)] dark:hover:bg-[var(--wc-dark-secondary)] transition text-start space-y-2 gap-3 dark:text-white/90">
<div class="flex gap-3 items-center ">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" class="size-6 w-5 h-5 dark:text-gray-400">
<path stroke-linecap="round" stroke-linejoin="round"
d="M4.5 12a7.5 7.5 0 0 0 15 0m-15 0a7.5 7.5 0 1 1 15 0m-15 0H3m16.5 0H21m-1.5 0H12m-8.457 3.077 1.41-.513m14.095-5.13 1.41-.513M5.106 17.785l1.15-.964m11.49-9.642 1.149-.964M7.501 19.795l.75-1.3m7.5-12.99.75-1.3m-6.063 16.658.26-1.477m2.605-14.772.26-1.477m0 17.726-.26-1.477M10.698 4.614l-.26-1.477M16.5 19.794l-.75-1.299M7.5 4.205 12 12m6.894 5.785-1.149-.964M6.256 7.178l-1.15-.964m15.352 8.864-1.41-.513M4.954 9.435l-1.41-.514M12.002 12l-3.75 6.495" />
</svg>
<span>@lang('wirechat::chat.group.info.actions.group_permissions.label')</span>
</div>
</button>
</x-wirechat::actions.open-chat-drawer>
</div>
@else
{{-- Exit Group --}}
<button wire:confirm="{{ __('wirechat::chat.group.info.actions.exit_group.confirmation_message') }}" wire:click="exitConversation"
class="cursor-pointer w-full py-5 px-8 hover:bg-[var(--wc-light-secondary)] dark:hover:bg-[var(--wc-dark-secondary)] transition flex gap-3 items-center text-red-500">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-box-arrow-right w-5 h-5" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0z" />
<path fill-rule="evenodd"
d="M15.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708.708L14.293 7.5H5.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708z" />
</svg>
<span>@lang('wirechat::chat.group.info.actions.exit_group.label')</span>
</button>
@endif
</footer>
</div>

View File

@@ -0,0 +1,162 @@
@php
$authIsAdminInGroup= $participant?->isAdmin();
$authIsOwner= $participant?->isOwner();
$isGroup= $conversation?->isGroup();
@endphp
<div x-ref="members"
class="h-[calc(100vh_-_6rem)] sm:h-[450px] bg-[var(--wc-light-primary)] dark:bg-[var(--wc-dark-primary)] dark:text-white border border-[var(--wc-light-secondary)] dark:border-[var(--wc-dark-secondary)] overflow-y-auto overflow-x-hidden ">
<header class=" sticky top-0 bg-[var(--wc-light-primary)] dark:bg-[var(--wc-dark-primary)] z-10 p-2">
<div class="flex items-center justify-center pb-2">
<x-wirechat::actions.close-modal>
<button dusk="close_modal_button"
class="p-2 ml-0 text-gray-600 hover:bg-[var(--wc-light-secondary)] dark:hover:bg-[var(--wc-dark-secondary)] dark:hover:text-white rounded-full hover:text-gray-800 ">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class=" w-5 w-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
</svg>
</button>
</x-wirechat::actions.close-modal>
<h3 class=" mx-auto font-semibold ">{{__('wirechat::chat.group.members.heading.label')}} </h3>
</div>
{{-- Member limit error --}}
<section class="flex flex-wrap items-center px-0 border-b dark:border-[var(--wc-dark-secondary)]">
<input type="search" id="users-search-field" wire:model.live.debounce='search' autocomplete="off"
placeholder="{{__('wirechat::chat.group.members.inputs.search.placeholder')}}"
class=" w-full border-0 w-auto dark:bg-[var(--wc-dark-primary)] outline-hidden focus:outline-hidden bg-[var(--wc-dark-parimary)] rounded-lg focus:ring-0 hover:ring-0">
</section>
</header>
<div class="relative w-full p-2 ">
{{-- <h5 class="text font-semibold text-gray-800 dark:text-gray-100">Recent Chats</h5> --}}
<section class="my-4 grid">
@if (count($participants)!=0)
<ul class="overflow-auto flex flex-col">
@foreach ($participants as $key => $participant)
@php
$loopParticipantIsAuth =
$participant->participantable_id == auth()->id() &&
$participant->participantable_type == auth()->user()->getMorphClass();
@endphp
<li x-data="{ open: false }" x-ref="button" @click="open = ! open" x-init="$watch('open', value => {
$refs.members.style.overflow = value ? 'hidden' : '';
})"
aria-modal="true"
tabindex="0"
x-on:keydown.escape.stop="open=false"
@click.away ="open=false;" wire:key="users-{{ $key }}"
:class="!open || 'bg-[var(--wc-light-secondary)] dark:bg-[var(--wc-dark-secondary)]'"
class="flex cursor-pointer group gap-2 items-center overflow-x-hidden p-2 py-3">
<label class="flex cursor-pointer gap-2 items-center w-full">
<x-wirechat::avatar src="{{ $participant->participantable->cover_url }}"
class="w-10 h-10" />
<div class="grid grid-cols-12 w-full ">
<h6 @class(['transition-all truncate group-hover:underline col-span-10' ])>
{{ $loopParticipantIsAuth ? 'You' : $participant->participantable->display_name }}</h6>
@if ($participant->isOwner()|| $participant->isAdmin())
<span style="background-color: var(--wirechat-primary-color);" class=" flex items-center col-span-2 text-white text-xs font-medium ml-auto px-2.5 py-px rounded-sm ">
{{$participant->isOwner()? __('wirechat::chat.group.members.labels.owner'): __('wirechat::chat.group.members.labels.admin')}}
</span>
@endif
</div>
<div x-show="open" x-anchor.bottom-end="$refs.button"
class="ml-auto bg-[var(--wc-light-secondary)] dark:bg-[var(--wc-dark-secondary)] border-[var(--wc-light-primary) dark:border-[var(--wc-dark-primary)] py-4 shadow-sm border rounded-md grid space-y-2 w-52">
{{-- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6 text-gray-600 dark:text-gray-300 w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
</svg> --}}
<x-wirechat::dropdown-button wire:click="sendMessage('{{ $participant->id }}')"
class="truncate ">
@if ($loopParticipantIsAuth)
{{__('wirechat::chat.group.members.actions.send_message_to_yourself.label')}}
@else
{{__('wirechat::chat.group.members.actions.send_message_to_member.label',['member'=>$participant->participantable?->display_name ])}}
@endif
</x-wirechat::dropdown-button>
@if ($authIsAdminInGroup || $authIsOwner)
{{-- Only show admin actions to owner of group and if is not the current loop --}}
{{--AND We only want to show admin actions if participant is not owner --}}
@if ($authIsOwner && !$loopParticipantIsAuth)
@if ($participant->isAdmin())
<x-wirechat::dropdown-button
wire:click="dismissAdmin('{{ $participant->id }}')"
wire:confirm="{{__('wirechat::chat.group.members.actions.dismiss_admin.confirmation_message',['member'=>$participant->participantable?->display_name])}}"
class=" ">
{{__('wirechat::chat.group.members.actions.dismiss_admin.label')}}
</x-wirechat::dropdown-button>
@else
<x-wirechat::dropdown-button
wire:click="makeAdmin('{{ $participant->id }}')"
wire:confirm="{{__('wirechat::chat.group.members.actions.make_admin.confirmation_message',['member'=>$participant->participantable?->display_name])}}"
class=" ">
{{__('wirechat::chat.group.members.actions.make_admin.label')}}
</x-wirechat::dropdown-button>
@endif
@endif
{{--AND We only want to show remove actions if participant is not owner of conversation because we don't want to remove owner--}}
@if (!$participant->isOwner() && !$loopParticipantIsAuth && !$participant->isAdmin())
<x-wirechat::dropdown-button
wire:click="removeFromGroup('{{ $participant->id }}')"
wire:confirm="{{__('wirechat::chat.group.members.actions.remove_from_group.confirmation_message',['member'=>$participant->participantable?->display_name])}}"
class="text-red-500 ">
{{__('wirechat::chat.group.members.actions.remove_from_group.label')}}
</x-wirechat::dropdown-button>
@endif
@else
@endif
</div>
</label>
</li>
@endforeach
</ul>
{{-- Load more button --}}
@if ($canLoadMore)
<section class="w-full justify-center flex my-3">
<button dusk="loadMoreButton" @click="$wire.loadMore()"
class=" text-sm dark:text-white hover:text-gray-700 transition-colors dark:hover:text-gray-500 dark:gray-200">
{{__('wirechat::chat.group.members.actions.load_more.label')}}
</button>
</section>
@endif
@else
<span class="m-auto">{{__('wirechat::chat.group.members.labels.no_members_found')}}</span>
@endif
</section>
</div>
</div>

View File

@@ -0,0 +1,148 @@
<div class="bg-[var(--wc-light-primary)] dark:bg-[var(--wc-dark-primary)] overfo opaticy-100 min-h-screen w-full">
<section class="flex gap-4 z-10 items-center p-5 sticky top-0 bg-[var(--wc-light-primary)] dark:bg-[var(--wc-dark-primary)] ">
<button wire:click="$dispatch('closeChatDrawer')" class="focus:outline-hidden"> <svg class="w-7 h-7"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg> </button>
<h3>{{__('wirechat::chat.group.permisssions.heading.label')}} </h3>
</section>
<div class="">
<section >
<h5 class="w-full text-start py-4 bg-[var(--wc-light-secondary)] dark:bg-[var(--wc-dark-secondary)] px-4">
{{__('wirechat::chat.group.permisssions.labels.members_can')}}:
</h5>
<ul class="space-y-2">
{{-- Edit Group Settings --}}
<li class="w-full flex p-5">
<span class="w-12">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="size-6 w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round"
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" />
</svg>
</span>
<span class="w-full text-start">
<h5 class="font-medium">{{__('wirechat::chat.group.permisssions.actions.edit_group_information.label')}}</h5>
<p>@lang('wirechat::chat.group.permisssions.actions.edit_group_information.helper_text')</p>
</span>
<span class="w-12">
<label class="inline-flex items-center cursor-pointer">
<input wire:model.live.debounce="allow_members_to_edit_group_info" type="checkbox" class="sr-only peer">
<div class="relative w-11 h-6 peer-focus:outline-hidden rounded-full peer
bg-[var(--wc-light-secondary)] dark:bg-[var(--wc-dark-secondary)]
shadow-2xs
peer-checked:border-[var(--wc-brand-primary)]
peer-checked:after:translate-x-full peer-checked:rtl:after:-translate-x-full
peer-checked:dark:border-[var(--wc-dark-primary)] peer-checked:border-[var(--wc-light-primary)]
after:content-[''] after:absolute after:top-[2px]
after:start-[2px] after:bg-white dark:after:bg-gray-100 after:shadow
peer-checked:after:bg-[var(--wc-brand-primary)] peer-checked:dark:after:bg-[var(--wc-brand-primary)]
peer-checked:after:border-[var(--wc-brand-primary)] peer-checked:dark:after:border-[var(--wc-brand-primary)]
dark:after:border-[var(--wc-dark-primary)] after:border-[var(--wc-light-primary)] after:border
after:rounded-full after:h-5 after:w-5 after:transition-all ease-in-out">
</div>
</label>
</span>
</li>
{{-- Send Messages --}}
<li class="w-full flex items-center p-5">
<span class="w-12">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.6" stroke="currentColor" class="size-6 w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.625 9.75a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H8.25m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H12m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0h-.375m-13.5 3.01c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.184-4.183a1.14 1.14 0 0 1 .778-.332 48.294 48.294 0 0 0 5.83-.498c1.585-.233 2.708-1.626 2.708-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z" />
</svg>
</span>
<span class="w-full text-start">
<h5 class="font-medium">@lang('wirechat::chat.group.permisssions.actions.send_messages.label')</h5>
</span>
<span class="w-12">
<label class="inline-flex items-center cursor-pointer">
<input wire:model.live.debounce="allow_members_to_send_messages" type="checkbox" class="sr-only peer">
<div class="relative w-11 h-6 peer-focus:outline-hidden rounded-full peer
bg-[var(--wc-light-secondary)] dark:bg-[var(--wc-dark-secondary)]
shadow-2xs
peer-checked:border-[var(--wc-brand-primary)]
peer-checked:after:translate-x-full peer-checked:rtl:after:-translate-x-full
peer-checked:dark:border-[var(--wc-dark-primary)] peer-checked:border-[var(--wc-light-primary)]
after:content-[''] after:absolute after:top-[2px]
after:start-[2px] after:bg-white dark:after:bg-gray-100 after:shadow
peer-checked:after:bg-[var(--wc-brand-primary)] peer-checked:dark:after:bg-[var(--wc-brand-primary)]
peer-checked:after:border-[var(--wc-brand-primary)] peer-checked:dark:after:border-[var(--wc-brand-primary)]
dark:after:border-[var(--wc-dark-primary)] after:border-[var(--wc-light-primary)] after:border
after:rounded-full after:h-5 after:w-5 after:transition-all ease-in-out">
</div>
</label>
</span>
</li>
{{-- Add other members --}}
<li class="w-full flex items-center p-5">
<span class="w-12">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-6 w-6 h-6 text-gray-500 dark:text-white/90">
<path d="M5.25 6.375a4.125 4.125 0 1 1 8.25 0 4.125 4.125 0 0 1-8.25 0ZM2.25 19.125a7.125 7.125 0 0 1 14.25 0v.003l-.001.119a.75.75 0 0 1-.363.63 13.067 13.067 0 0 1-6.761 1.873c-2.472 0-4.786-.684-6.76-1.873a.75.75 0 0 1-.364-.63l-.001-.122ZM18.75 7.5a.75.75 0 0 0-1.5 0v2.25H15a.75.75 0 0 0 0 1.5h2.25v2.25a.75.75 0 0 0 1.5 0v-2.25H21a.75.75 0 0 0 0-1.5h-2.25V7.5Z" />
</svg>
</span>
<span class="w-full text-start">
<h5 class="font-medium">@lang('wirechat::chat.group.permisssions.actions.add_other_members.label')</h5>
</span>
<span class="w-12">
<label class="inline-flex items-center cursor-pointer">
<input wire:model.live.debounce="allow_members_to_add_others" type="checkbox" class="sr-only peer">
<div class="relative w-11 h-6 peer-focus:outline-hidden rounded-full peer
bg-[var(--wc-light-secondary)] dark:bg-[var(--wc-dark-secondary)]
shadow-2xs
peer-checked:border-[var(--wc-brand-primary)]
peer-checked:after:translate-x-full peer-checked:rtl:after:-translate-x-full
peer-checked:dark:border-[var(--wc-dark-primary)] peer-checked:border-[var(--wc-light-primary)]
after:content-[''] after:absolute after:top-[2px]
after:start-[2px] after:bg-white dark:after:bg-gray-100 after:shadow
peer-checked:after:bg-[var(--wc-brand-primary)] peer-checked:dark:after:bg-[var(--wc-brand-primary)]
peer-checked:after:border-[var(--wc-brand-primary)] peer-checked:dark:after:border-[var(--wc-brand-primary)]
dark:after:border-[var(--wc-dark-primary)] after:border-[var(--wc-light-primary)] after:border
after:rounded-full after:h-5 after:w-5 after:transition-all ease-in-out">
</div>
</label>
</span>
</li>
</ul>
</section>
</div>
</div>