book cases added

This commit is contained in:
Benjamin Takats
2022-12-07 14:57:15 +01:00
parent d1fcde87e6
commit 840f79e7fc
59 changed files with 2175 additions and 142 deletions

View File

@@ -1,11 +1,21 @@
<div>
@php
$a = (bool)rand(0, 1);
@endphp
@if($a)
<img class="h-12" src="{{ asset('img/social_credit_minus.webp') }}" alt="">
@endif
@if(!$a)
<img class="h-12" src="{{ asset('img/social_credit_plus.webp') }}" alt="">
@endif
<div class="flex flex-col space-y-1">
@auth
@if($row->orange_pilled)
<img class="aspect-auto max-h-12" src="{{ asset('img/social_credit_plus.webp') }}" alt="">
@endif
@if(!$row->orange_pilled)
<img class="aspect-auto max-h-12" src="{{ asset('img/social_credit_minus.webp') }}" alt="">
@endif
<div class="flex items-center space-x-1">
<x-button wire:click="viewHistoryModal({{ $row->id }})">💊 Orange Pill Now</x-button>
<x-button :href="route('comment.bookcase', ['bookCase' => $row->id])">Kommentare</x-button>
</div>
@else
<div>
<x-badge amber>
<i class="fa fa-thin fa-shelves-empty mr-2"></i>
{{ __('noch keine Bitcoin-Bücher') }}
</x-badge>
</div>
@endauth
</div>

View File

@@ -9,32 +9,46 @@
@googlefonts
<!-- Scripts -->
<script src="https://kit.fontawesome.com/03bc14bd1e.js" crossorigin="anonymous"></script>
@mapscripts
<wireui:scripts/>
<x-comments::scripts />
@vite(['resources/css/app.css', 'resources/js/app.js'])
<!-- Styles -->
<x-comments::styles />
@livewireStyles
@mapstyles
<style>
#seekObjContainer {
position: relative;
width: 400px;
margin: 0 5px;
height: 5px;
}
.comments {
--comments-color-background: rgb(34, 34, 34);
--comments-color-background: rgb(34, 34, 34);
--comments-color-background-nested: rgb(34, 34, 34);
--comments-color-background-paper: rgb(55, 51, 51);
--comments-color-background-info: rgb(104, 89, 214);
#seekObj {
position: relative;
width: 100%;
height: 100%;
background-color: #e3e3e3;
border: 1px solid black;
}
--comments-color-reaction: rgb(59, 59, 59);
--comments-color-reaction-hover: rgb(65, 63, 63);
--comments-color-reacted: rgba(67, 56, 202, 0.25);
--comments-color-reacted-hover: rgba(67, 56, 202, 0.5);
#percentage {
position: absolute;
left: 0;
top: 0;
height: 100%;
background-color: coral;
--comments-color-border: rgb(221, 221, 221);
--comments-color-text:white;
--comments-color-text-dimmed: rgb(164, 164, 164);
--comments-color-text-inverse: white;
--comments-color-accent: rgba(67, 56, 202);
--comments-color-accent-hover: rgba(67, 56, 202, 0.75);
--comments-color-danger: rgb(225, 29, 72);
--comments-color-danger-hover: rgb(225, 29, 72, 0.75);
--comments-color-success: rgb(10, 200, 134);
--comments-color-success-hover: rgb(10, 200, 134, 0.75);
--comments-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
}
.comments-button {
background-color: #F7931A !important;
}
[x-cloak] {
@@ -43,7 +57,7 @@
</style>
</head>
<body class="font-sans antialiased bg-21gray dark">
<x-notifications z-index="z-50"/>
<x-notifications z-index="z-50" blur="md" align="center"/>
<x-jet-banner/>
<div class="min-h-screen">
@auth

View File

@@ -10,17 +10,51 @@
<!-- Scripts -->
<script src="https://kit.fontawesome.com/03bc14bd1e.js" crossorigin="anonymous"></script>
<wireui:scripts/>
<x-comments::scripts />
@vite(['resources/css/app.css', 'resources/js/app.js'])
<!-- Styles -->
@livewireStyles
<style>
.comments {
--comments-color-background: rgb(34, 34, 34);
--comments-color-background: rgb(34, 34, 34);
--comments-color-background-nested: rgb(34, 34, 34);
--comments-color-background-paper: rgb(55, 51, 51);
--comments-color-background-info: rgb(104, 89, 214);
--comments-color-reaction: rgb(59, 59, 59);
--comments-color-reaction-hover: rgb(65, 63, 63);
--comments-color-reacted: rgba(67, 56, 202, 0.25);
--comments-color-reacted-hover: rgba(67, 56, 202, 0.5);
--comments-color-border: rgb(221, 221, 221);
--comments-color-text:white;
--comments-color-text-dimmed: rgb(164, 164, 164);
--comments-color-text-inverse: white;
--comments-color-accent: rgba(67, 56, 202);
--comments-color-accent-hover: rgba(67, 56, 202, 0.75);
--comments-color-danger: rgb(225, 29, 72);
--comments-color-danger-hover: rgb(225, 29, 72, 0.75);
--comments-color-success: rgb(10, 200, 134);
--comments-color-success-hover: rgb(10, 200, 134, 0.75);
--comments-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
}
.comments-button {
background-color: #F7931A !important;
}
[x-cloak] {
display: none !important;
}
</style>
</head>
<body class="font-sans antialiased bg-21gray dark">
<x-notifications z-index="z-50"/>
<x-notifications z-index="z-50" blur="md" align="center"/>
{{ $slot }}
@stack('modals')
@livewireScripts

View File

@@ -0,0 +1,123 @@
<div class="bg-21gray flex flex-col h-screen justify-between">
<script src="{{ asset('earth/miniature.earth.js') }}"></script>
<style>
.earth-container::after {
content: "";
position: absolute;
height: 22%;
bottom: 4%;
left: 13%;
right: 13%;
}
</style>
{{-- HEADER --}}
<div>
<section class="w-full">
<div class="max-w-screen-2xl mx-auto px-2 sm:px-10">
<div
class="relative sm:sticky sm:top-0 bg-21gray z-10 flex flex-col flex-wrap items-center justify-between py-7 mx-auto md:flex-row max-w-screen-2xl">
<div class="relative flex flex-col md:flex-row">
<a href="{{ route('search.city', ['country' => $c]) }}"
class="flex items-center mb-5 font-medium text-gray-900 lg:w-auto lg:items-center lg:justify-center md:mb-0">
<img src="{{ asset('img/einundzwanzig-horizontal-inverted.svg') }}">
</a>
<nav
class="flex flex-wrap items-center mb-5 text-lg md:mb-0 md:pl-8 md:ml-8 md:border-l md:border-gray-800">
<a href="{{ route('search.city', ['country' => $c, '#table']) }}"
class="{{ request()->routeIs('search.city') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Städte</a>
<a href="{{ route('search.lecturer', ['country' => $c, '#table']) }}"
class="{{ request()->routeIs('search.lecturer') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Dozenten</a>
<a href="{{ route('search.venue', ['country' => $c, '#table']) }}"
class="{{ request()->routeIs('search.venue') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Veranstaltungs-Orte</a>
<a href="{{ route('search.course', ['country' => $c, '#table']) }}"
class="{{ request()->routeIs('search.course') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Kurse</a>
<a href="{{ route('search.event', ['country' => $c, '#table']) }}"
class="{{ request()->routeIs('search.event') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Termine</a>
<a href="{{ route('library', ['country' => $c]) }}"
class="{{ request()->routeIs('library') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Bibliothek</a>
<a href="{{ route('search.bookcases', ['country' => $c]) }}"
class="{{ request()->routeIs('search.bookcases') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Bücher-Schränke</a>
@if(auth()->user()?->is_lecturer)
<a href="{{ route('library.lecturer', ['country' => $c]) }}"
class="{{ request()->routeIs('library.lecturer') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Dozenten-Bibliothek</a>
@endif
</nav>
</div>
@auth
<div></div>
@else
<div class="inline-flex items-center ml-5 my-2 text-lg space-x-6 lg:justify-end">
<a href="{{ route('auth.ln') }}"
class="text-xs sm:text-base font-medium leading-6 text-gray-400 hover:text-gray-300 whitespace-no-wrap transition duration-150 ease-in-out">
Login
</a>
<a href="{{ route('auth.ln') }}"
class="text-xs sm:text-base inline-flex items-center justify-center px-4 py-2 font-medium leading-6 text-gray-200 hover:text-white whitespace-no-wrap bg-gray-800 border border-transparent rounded shadow-sm hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-800">
Registrieren
</a>
</div>
@endauth
</div>
</div>
</section>
</div>
{{-- MAIN --}}
<section class="w-full mb-12">
<div class="max-w-screen-2xl mx-auto px-2 sm:px-10">
<div class="flex items-center justify-end space-x-2 my-6">
<x-button primary :href="route('search.bookcases', ['country' => $c])">
<i class="fa fa-thin fa-arrow-left"></i>
Zurück zur Übersicht
</x-button>
</div>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div
class="relative flex items-center space-x-3 rounded-lg border border-gray-300 bg-white px-6 py-5 shadow-sm focus-within:ring-2 focus-within:ring-indigo-500 focus-within:ring-offset-2 hover:border-gray-400">
{{--<div class="flex-shrink-0">
<img class="h-10 w-10 rounded-full" src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
</div>--}}
<div class="min-w-0 flex-1">
<div class="focus:outline-none">
<p class="text-sm font-medium text-gray-900">Name</p>
<p class="truncate text-sm text-gray-500">{{ $bookCase->title }}</p>
<p class="text-sm font-medium text-gray-900">Link</p>
<p class="text-sm text-gray-500">
<a target="_blank"
href="{{ $this->url_to_absolute($bookCase->homepage) }}">{{ $this->url_to_absolute($bookCase->homepage) }}</a>
</p>
<p class="text-sm font-medium text-gray-900">Adresse</p>
<p class="truncate text-sm text-gray-500">{{ $bookCase->address }}</p>
</div>
</div>
</div>
<div class="rounded">
@map([
'lat' => $bookCase->lat,
'lng' => $bookCase->lon,
'zoom' => 24,
'markers' => [
[
'title' => $bookCase->title,
'lat' => $bookCase->lat,
'lng' => $bookCase->lon,
'url' => 'https://gonoware.com',
'icon' => asset('img/btc-logo-6219386_1280.png'),
'icon_size' => [42, 42],
],
],
])
</div>
</div>
<div class="my-4">
<livewire:comments :model="$bookCase"/>
</div>
</div>
</section>
{{-- FOOTER --}}
<livewire:frontend.footer/>
</div>

View File

@@ -33,6 +33,8 @@
class="{{ request()->routeIs('search.event') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Termine</a>
<a href="{{ route('library', ['country' => $c]) }}"
class="{{ request()->routeIs('library') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Bibliothek</a>
<a href="{{ route('search.bookcases', ['country' => $c]) }}"
class="{{ request()->routeIs('search.bookcases') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Bücher-Schränke</a>
@if(auth()->user()?->is_lecturer)
<a href="{{ route('library.lecturer', ['country' => $c]) }}"
class="{{ request()->routeIs('library.lecturer') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Dozenten-Bibliothek</a>

View File

@@ -35,6 +35,8 @@
class="{{ request()->routeIs('search.event') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Termine</a>
<a href="{{ route('library', ['country' => $c]) }}"
class="{{ request()->routeIs('library') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Bibliothek</a>
<a href="{{ route('search.bookcases', ['country' => $c]) }}"
class="{{ request()->routeIs('search.bookcases') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Bücher-Schränke</a>
@if(auth()->user()?->is_lecturer)
<a href="{{ route('library.lecturer', ['country' => $c]) }}"
class="{{ request()->routeIs('library.lecturer') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Dozenten-Bibliothek</a>
@@ -79,7 +81,7 @@
init() {
this.earth = new Earth(this.$refs.myearth, {
location : {lat: {{ $bookCases->first()->lat }}, lng: {{ $bookCases->first()->lon }}},
zoom: 2,
zoom: 1,
light: 'sun',
polarLimit: 0.6,

View File

@@ -0,0 +1,42 @@
<x-jet-dialog-modal wire:model="viewingModal" maxWidth="screen" bg="bg-21gray">
<x-slot name="title">
<div class="text-gray-200">
{{ __('Orange Pill Book Case') }}
</div>
</x-slot>
<x-slot name="content">
<div class="space-y-4 mt-16 flex flex-col justify-center">
<div class="col-span-6 sm:col-span-4">
<x-input
min="1"
type="number"
wire:model.debounce="orangepill.amount"
label="Anzahl der Bücher"
placeholder="Anzahl der Bücher"
corner-hint="Wie viele Bitcoin-Bücher hast du reingestellt?"
/>
</div>
<div class="col-span-6 sm:col-span-4">
<x-datetime-picker
label="Datum"
placeholder="Datum"
display-format="DD.MM.YYYY"
wire:model.defer="orangepill.date"
without-time
corner-hint="Wann hast du Bitcoin-Bücher reingestellt?"
/>
</div>
<div class="col-span-6 sm:col-span-4">
<x-textarea wire:model.defer="orangepill.comment" label="Kommentar" placeholder="Kommentar"
corner-hint="Zum Beispiel welche Bücher du reingestellt hast."/>
</div>
</div>
</x-slot>
<x-slot name="footer">
<x-jet-secondary-button wire:click="resetModal" wire:loading.attr="disabled">
💊 @lang('Orange Pill Now')
</x-jet-secondary-button>
</x-slot>
</x-jet-dialog-modal>

View File

@@ -0,0 +1,15 @@
@php
$defaultImage = Spatie\Comments\Support\Config::getGravatarDefaultImage();
$defaultAvatar = "https://www.gravatar.com/avatar/unknown?d={$defaultImage}";
if ($user = auth()->user()) {
$segment = md5(strtolower($user->email));
$defaultAvatar = "https://www.gravatar.com/avatar/{$segment}?d={$defaultImage}";
}
@endphp
<img
class="comments-avatar"
src="{{ isset($comment) && $comment->commentatorProperties() ? $comment->commentatorProperties()->avatar : $defaultAvatar }}"
alt="avatar"
>

View File

@@ -0,0 +1,12 @@
<button
type="{{ isset($submit) && $submit ? 'submit' : 'button' }}"
@class([
'comments-button',
'is-small' => isset($small) && $small,
'is-danger' => isset($danger) && $danger,
'is-link' => isset($link) && $link,
])
{{ $attributes->except('type', 'size', 'submit') }}
>
{{ $slot }}
</button>

View File

@@ -0,0 +1,7 @@
<time datetime="$date->format('Y-m-d H:i:s')" class="comments-date">
@if($date->diffInMinutes() < 1)
{{ __('comments::comments.just_now') }}
@else
{{ $date->diffForHumans() }}
@endif
</time>

View File

@@ -0,0 +1,104 @@
<div
x-data="compose({ text: @entangle($model), autofocus: @json($autofocus ?? false) })"
x-init="
$wire.on('comment', clear);
@isset($comment)
$wire.on('reply-{{ $comment->id }}', () => {
clear();
});
@endisset
"
>
<div wire:ignore>
<textarea placeholder="{{ $placeholder ?? '' }}"></textarea>
</div>
<div class="comments-form-editor-tip">
You can use <a href="https://spatie.be/markdown" target="_blank" rel="nofollow noopener noreferrer">Markdown</a>
</div>
</div>
@push('comments-scripts')
<script>
document.addEventListener("alpine:init", () => {
window.Alpine.data("compose", ({ text, autofocus = false } = {}) => {
// Store the editor as a non-reactive instance property
let editor;
return {
text,
init() {
if (editor) {
return;
}
const textarea = this.$el.querySelector("textarea");
if (!textarea) {
return;
}
this.loadEasyMDE().then(() => {
editor = new window.EasyMDE({
element: textarea,
hideIcons: [
"heading",
"image",
"preview",
"side-by-side",
"fullscreen",
"guide",
],
spellChecker: false,
status: false,
insertTexts: {
link: ["[", "](https://)"],
},
});
editor.value(this.text);
if (autofocus) {
editor.codemirror.focus();
editor.codemirror.setCursor(editor.codemirror.lineCount(), 0);
}
editor.codemirror.on("change", () => {
this.text = editor.value();
});
});
},
clear() {
editor.value("");
},
loadEasyMDE() {
if (window.EasyMDE) {
return Promise.resolve();
}
const loadScript = new Promise((resolve) => {
const script = document.createElement("script");
script.src = "https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js";
script.addEventListener("load", resolve);
document.getElementsByTagName("head")[0].appendChild(script);
});
const loadCss = new Promise((resolve) => {
const link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = "https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css";
link.addEventListener("load", resolve);
document.getElementsByTagName("head")[0].appendChild(link);
});
return Promise.all([loadScript, loadCss]);
},
};
});
});
</script>
@endpush

View File

@@ -0,0 +1 @@
<textarea wire:model.lazy="{{ $model }}" @isset($autofocus) autofocus @endisset class="comments-textarea"></textarea>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="comments-icon"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>

After

Width:  |  Height:  |  Size: 219 B

View File

@@ -0,0 +1 @@
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="comments-icon"><path stroke-width="0" d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"></path></svg>

After

Width:  |  Height:  |  Size: 645 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="comments-icon"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>

After

Width:  |  Height:  |  Size: 323 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="comments-icon"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"/></svg>

After

Width:  |  Height:  |  Size: 295 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="comments-icon"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z"/></svg>

After

Width:  |  Height:  |  Size: 316 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="comments-icon"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>

After

Width:  |  Height:  |  Size: 283 B

View File

@@ -0,0 +1,14 @@
<div
x-cloak
@class(['comments-modal', 'is-compact' => $compact ?? false, 'is-left' => $left ?? false, 'is-bottom' => $bottom ?? false])
{{ $attributes }}
>
@isset($title)
<p class="comments-modal-title">
{{ $title }}
</p>
@endisset
<div class="comments-modal-contents">
{{ $slot }}
</div>
</div>

View File

@@ -0,0 +1,9 @@
<script>
if (window.Alpine) {
console.warn(
'Laravel Comments scripts were loaded after Alpine. ' +
'Please ensure Alpine is loaded last so Laravel Comments can initialize first.'
);
}
</script>
@stack('comments-scripts')

View File

@@ -0,0 +1,3 @@
<style>
{{ $stylesheet }}
</style>

View File

@@ -0,0 +1,196 @@
<div
id="comment-{{ $comment->id }}"
class="comments-group"
x-data="{ confirmDelete: false, urlCopied: false }"
x-effect="
if (urlCopied) {
window.navigator.clipboard.writeText(window.location.href.split('#')[0] + '#comment-{{ $comment->id }}');
window.setTimeout(() => urlCopied = false, 2000);
}
"
>
<div class="comments-comment">
@if($showAvatar)
<x-comments::avatar :comment="$comment"/>
@endif
<div class="comments-comment-inner">
<div class="comments-comment-header">
@if($url = $comment->commentatorProperties()?->url)
<a href="{{ $url }}">
{{ $comment->commentatorProperties()->name }}
</a>
@else
{{ $comment->commentatorProperties()?->name ?? __('comments::comments.guest') }}
@endif
<ul class="comments-comment-header-actions">
<li>
<a
href="#comment-{{ $comment->id }}"
@click.prevent="urlCopied = true"
>
<x-comments::date :date="$comment->created_at"/>
<span class="comments-comment-header-copied" x-show="urlCopied" style="display: none;">
{{ __('comments::comments.copied') }}!
</span>
</a>
</li>
@if($writable)
@can('update', $comment)
<li>
<a href="#" wire:click.prevent="startEditing" aria-role="button">{{__('comments::comments.edit')}}</a>
</li>
@endcan
@can('delete', $comment)
<li>
<a href="#" @click.prevent="confirmDelete = true" aria-role="button">{{__('comments::comments.delete')}}</a>
<x-comments::modal
right
bottom
x-show="confirmDelete"
@click.outside="confirmDelete = false"
:title="__('comments::comments.delete_confirmation_title')"
>
<p>{{ __('comments::comments.delete_confirmation_text') }}</p>
<x-comments::button danger small wire:click="deleteComment">
{{ __('comments::comments.delete') }}
</x-comments::button>
</x-comments::modal>
</li>
@endcan
@endif
@include('comments::extraCommentHeaderActions')
</ul>
</div>
@if($comment->isPending())
<div class="comments-approval">
<span>
{{__('comments::comments.awaits_approval')}}
</span>
<span class="comments-approval-buttons">
@can('reject', $comment)
<button
class="comments-button is-small is-danger"
wire:click="reject">
{{__('comments::comments.reject_comment')}}
</button>
@endcan
@can('approve', $comment)
<button
class="comments-button is-small"
wire:click="approve">
{{__('comments::comments.approve_comment')}}
</button>
@endcan
</span>
</div>
@endif
@if($isEditing)
<div class="comments-form">
<form class="comments-form-inner" wire:submit.prevent="edit">
<x-dynamic-component
:component="\Spatie\LivewireComments\Support\Config::editor()"
model="editText"
:comment="$comment"
autofocus
/>
@error('editText')
<p class="comments-error">
{{ $message }}
</p>
@enderror
<x-comments::button submit>
{{ __('comments::comments.edit_comment') }}
</x-comments::button>
<x-comments::button link wire:click="stopEditing">
{{ __('comments::comments.cancel') }}
</x-comments::button>
</form>
</div>
@else
<div class="comment-text">
{!! $comment->text !!}
</div>
@if($writable || $comment->reactions->summary()->isNotEmpty())
<div class="comments-reactions">
@foreach($comment->reactions->summary() as $summary)
<div
wire:key="{{ $comment->id }}{{$summary['reaction']}}"
@auth
wire:click="toggleReaction('{{ $summary['reaction'] }}')"
@endauth
@class(['comments-reaction', 'is-reacted' => $summary['commentator_reacted']])
>
{{ $summary['reaction'] }} {{ $summary['count'] }}
</div>
@endforeach
@if($writable)
<div
x-cloak
x-data="{ open: false }"
@click.outside="open = false"
class="comments-reaction-picker"
>
@can('react', $comment)
<button class="comments-reaction-picker-trigger" type="button"
@click="open = !open">
<x-comments::icons.smile/>
</button>
<x-comments::modal x-show="open" compact left>
<div class="comments-reaction-picker-reactions">
@foreach(config('comments.allowed_reactions') as $reaction)
@php
$commentatorReacted = ! is_bool(array_search(
$reaction,
array_column($comment->reactions->toArray(), 'reaction'),
));
@endphp
<button
type="button"
@class(['comments-reaction-picker-reaction', 'is-reacted' => $commentatorReacted])
wire:click="toggleReaction('{{ $reaction }}')"
>
{{ $reaction }}
</button>
@endforeach
</div>
</x-comments::modal>
@endcan
</div>
@endif
</div>
@endif
@endif
</div>
</div>
@if($showReplies)
@if($comment->isTopLevel())
<div class="comments-nested">
@if($this->newestFirst)
@if(auth()->check() || config('comments.allow_anonymous_comments'))
@include('comments::livewire.partials.replyTo')
@endif
@endif
@foreach ($comment->nestedComments as $nestedComment)
@can('see', $nestedComment)
<livewire:comments-comment
:key="$nestedComment->id"
:comment="$nestedComment"
:show-avatar="$showAvatar"
:newest-first="$newestFirst"
:writable="$writable"
/>
@endcan
@endforeach
@if(! $this->newestFirst)
@if(auth()->check() || config('comments.allow_anonymous_comments'))
@include('comments::livewire.partials.replyTo')
@endif
@endif
</div>
@endif
@endif
</div>

View File

@@ -0,0 +1,61 @@
@php
use Spatie\Comments\Enums\NotificationSubscriptionType;
@endphp
<section class="comments {{ $newestFirst ? 'comments-newest-first' : '' }}">
<header class="comments-header">
@if($writable)
@auth
@if($showNotificationOptions)
<div x-data="{ subscriptionsOpen: false}" class="comments-subscription">
<button @click.prevent="subscriptionsOpen = true" class="comments-subscription-trigger">
{{ NotificationSubscriptionType::from($selectedNotificationSubscriptionType)->longDescription() }}
</button>
<x-comments::modal
bottom
compact
x-show="subscriptionsOpen"
@click.outside="subscriptionsOpen = false"
>
@foreach(NotificationSubscriptionType::cases() as $case)
<button class="comments-subscription-item" @click="subscriptionsOpen = false" wire:click="updateSelectedNotificationSubscriptionType('{{ $case->value }}')">
{{ $case->description() }}
</button>
@endforeach
</x-comments::modal>
</div>
@endif
@endif
@endauth
</header>
@if ($newestFirst)
@include('comments::livewire.partials.newComment')
@endif
@if($comments->count())
@foreach($comments as $comment)
@can('see', $comment)
<livewire:comments-comment
:key="$comment->id"
:comment="$comment"
:show-avatar="$showAvatars"
:newest-first="$newestFirst"
:writable="$writable"
:show-replies="$showReplies"
/>
@endcan
@endforeach
@if ($comments->hasPages())
{{ $comments->links() }}
@endif
@else
<p class="comments-no-comment-yet">{{ $noCommentsText ?? __('comments::comments.no_comments_yet') }}</p>
@endif
@if (! $newestFirst)
@include('comments::livewire.partials.newComment')
@endif
</section>

View File

@@ -0,0 +1,24 @@
@if($writable)
@can('createComment', $model)
<div class="comments-form">
@if($showAvatars)
<x-comments::avatar/>
@endif
<form class="comments-form-inner" wire:submit.prevent="comment">
<x-dynamic-component
:component="\Spatie\LivewireComments\Support\Config::editor()"
model="text"
:placeholder="__('comments::comments.write_comment')"
/>
@error('text')
<p class="comments-error">
{{ $message }}
</p>
@enderror
<x-comments::button submit>
{{ __('comments::comments.create_comment') }}
</x-comments::button>
</form>
</div>
@endcan
@endif

View File

@@ -0,0 +1,47 @@
@if($writable)
<div class="comments-form comments-reply">
@if($showAvatar)
<x-comments::avatar/>
@endif
<form class="comments-form-inner" wire:submit.prevent="reply">
<div
x-data="{ isExpanded: false }"
x-init="
$wire.on('reply-{{ $comment->id }}', () => {
isExpanded = false;
});
"
>
<input
x-show="!isExpanded"
@click="isExpanded = true"
@focus="isExpanded = true"
class="comments-placeholder"
placeholder="{{ __('comments::comments.write_reply') }}"
>
<div x-show="isExpanded">
<div>
<x-dynamic-component
:component="\Spatie\LivewireComments\Support\Config::editor()"
model="replyText"
:comment="$comment"
:placeholder="__('comments::comments.write_reply')"
autofocus
/>
@error('replyText')
<p class="comments-error">
{{ $message }}
</p>
@enderror
<x-comments::button submit>
{{ __('comments::comments.create_reply') }}
</x-comments::button>
<x-comments::button link @click="isExpanded = false">
{{ __('comments::comments.cancel') }}
</x-comments::button>
</div>
</div>
</div>
</form>
</div>
@endif

View File

@@ -0,0 +1,24 @@
@component('mail::message')
# {{ __('comments::notifications.approved_comment_mail_title', [
'commentable_name' => $topLevelComment->commentable->commentableName(),
'commentable_url' => $topLevelComment->commentable->commentUrl(),
'commentator_name' => $comment->commentatorProperties()->name ?? 'anonymous',
]) }}
{{ __('comments::notifications.approved_comment_mail_body', [
'commentable_name' => $topLevelComment->commentable->commentableName(),
'commentable_url' => $topLevelComment->commentable->commentUrl(),
'commentator_name' => $comment->commentatorProperties()->name ?? 'anonymous',
]) }}
{!! $comment->text !!}
@component('mail::button', ['url' => $comment->commentUrl()])
{{ __('comments::notifications.view_comment') }}
@endcomponent
@if($unsubscribeUrl = $commentator->unsubscribeFromCommentNotificationsUrl($comment))
<a href="{{ $unsubscribeUrl }}">Unsubscribe from receive notification about {{ $topLevelComment->commentable->commentableName() }}</a>
@endif
@endcomponent

View File

@@ -0,0 +1,20 @@
@component('mail::message')
{{ __('comments::notifications.pending_comment_mail_body', [
'commentable_name' => $topLevelComment->commentable->commentableName(),
'commentator_name' => $comment->commentatorProperties()->name ?? 'anonymous',
]) }}
[{{ __('comments::notifications.view_comment') }}]({{ $comment->commentUrl() }})
{!! $comment->text !!}
@component('mail::button', ['url' => $comment->approveUrl()])
{{ __('comments::notifications.approve_comment') }}
@endcomponent
@component('mail::button', ['url' => $comment->rejectUrl()])
{{ __('comments::notifications.reject_comment') }}
@endcomponent
@endcomponent

View File

@@ -0,0 +1,5 @@
<x-comments::signed-layout>
The comment has been approved.
</x-comments::signed-layout>

View File

@@ -0,0 +1,15 @@
<x-comments::signed-layout>
Do you want to approve the comment?
<form class="form" method="POST">
@csrf
<button id="confirmationButton" class="button" type="submit">Approve</button>
</form>
</x-comments::signed-layout>
<script>
document.getElementById("confirmationButton").click();
</script>

View File

@@ -0,0 +1,5 @@
<x-comments::signed-layout>
The comment has been rejected.
</x-comments::signed-layout>

View File

@@ -0,0 +1,14 @@
<x-comments::signed-layout>
Do you want to reject the comment?
<form class="form" method="POST">
@csrf
<button id="confirmationButton" class="button" type="submit">Approve</button>
</form>
</x-comments::signed-layout>
<script>
document.getElementById("confirmationButton").click();
</script>

View File

@@ -0,0 +1,5 @@
<x-comments::signed-layout>
You have been unsubscribed.
</x-comments::signed-layout>

View File

@@ -0,0 +1,5 @@
<x-comments::signed-layout>
You have been unsubscribed from every comment notification.
</x-comments::signed-layout>

View File

@@ -0,0 +1,14 @@
<x-comments::signed-layout>
Do you want to unsubscribe from every comment notification?
<form class="form" method="POST">
@csrf
<button id="confirmationButton" class="button" type="submit">Approve</button>
</form>
</x-comments::signed-layout>
<script>
document.getElementById("confirmationButton").click();
</script>

View File

@@ -0,0 +1,14 @@
<x-comments::signed-layout>
Do you want to unsubscribe?
<form class="form" method="POST">
@csrf
<button id="confirmationButton" class="button" type="submit">Approve</button>
</form>
</x-comments::signed-layout>
<script>
document.getElementById("confirmationButton").click();
</script>

View File

@@ -0,0 +1,10 @@
<html lang="en">
<head>
</head>
<body>
<div>
{{ $slot }}
</div>
</body>
</html>