Проверка и сохранение на основе выбора переключателя и аутентификации

Я столкнулся с тремя проблемами, которые все связаны с тем, что я изо всех сил пытаюсь добавить событие. @click="isQuestion = true" на радиостанциях в цикле и проверять при определенных условиях, в зависимости от того, какой переключатель выбран, например, если аутентифицирован, то сохраните идентификатор пользователя, но если не его анонимный отзыв, если дополнительный адрес электронной почты не предоставлен.

В базе данных есть четыре записи для типа билета, см. Изображение для лучшего объяснения:

Мне нужна помощь по трем вопросам:

  1. Показывать только если пользователь аутентифицирован
  2. Показать и скрыть, и если выбран переключатель, если выбрано что-то еще, показать и скрыть subject
  3. Проверять и сохранять информацию только в зависимости от выбора переключателя
    • Если выбран какой-либо переключатель, кроме проверки и сохранения и
    • Если выбран, подтвердить и сохранить все, кроме emailи data_protection

ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ : большая часть логики уже используется, чтобы скрыть определенные поля, если нет I have a question радио-кнопка выбирается, делая это x-show="!isQuestion" просто не уверен как привязать его к переключателям.

Любая помощь или руководство приветствуются

Создать компонент Livewire тикета

      <div x-data="{ isOpen: false, isQuestion: false, send: false }" @keydown.window.escape="isOpen = false" x-init="
         @this.on('change-send', () => {
             send = !send;
         })
    ">
    <div class="fixed bottom-0 right-0 top-0 flex items-center">
        <div class="transform -rotate-90 origin-bottom-right">
            <x-jet-button @click="isOpen = !isOpen" class="!rounded-none !rounded-t-lg !p-3">
                {{ __('Feedback') }}
            </x-jet-button>
        </div>
    </div>
    <div class="fixed inset-0 overflow-hidden pointer-events-none" x-cloak>
        <div class="absolute inset-0 overflow-hidden">
            <div x-show="isOpen" x-description="Background overlay, show/hide based on slide-over state." x-transition:enter="ease-in-out duration-500" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="ease-in-out duration-500" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="absolute inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
            <section class="absolute inset-y-0 right-0 pl-10 max-w-full flex" aria-labelledby="slide-over-heading">
                <div x-show="isOpen" x-description="Slide-over panel, show/hide based on slide-over state." x-transition:enter="transform transition ease-in-out duration-500 sm:duration-700" x-transition:enter-start="translate-x-full" x-transition:enter-end="translate-x-0" x-transition:leave="transform transition ease-in-out duration-500 sm:duration-700" x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full" class="relative w-screen max-w-md pointer-events-auto">
                    <div x-show="isOpen" x-description="Close button, show/hide based on slide-over state." x-transition:enter="ease-in-out duration-500" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="ease-in-out duration-500" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="absolute top-0 left-0 -ml-8 pt-4 pr-2 flex sm:-ml-10 sm:pr-4">
                        <button type="button" @click="isOpen = !isOpen" class="rounded-md text-gray-300 hover:text-white focus:outline-none focus:ring-2 focus:ring-white">
                            <span class="sr-only">Close panel</span>
                            <!-- Heroicon name: outline/x -->
                            <svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                            </svg>
                        </button>
                    </div>
                    <div class="h-full flex flex-col py-6 bg-white shadow-xl overflow-y-scroll">
                        <div x-show="!send" class="px-4 sm:px-6">
                            <h2 id="slide-over-heading" class="text-lg font-medium text-gray-900">
                                {{ __('Do you have any feedback?') }}
                            </h2>
                            <p class="text-sm leading-5 text-gray-700">
                                {{__('We appreciate your feedback. Would you change something? Do you think something is good? We look forward to any kind of feedback.')}}
                            </p>
                        </div>
                        <div x-show="send" class="mt-6 relative flex-1 flex px-4 sm:px-6 justify-center items-center">
                            <div class="flex flex-col justify-center">
                                <div class="flex justify-center">
                                    <!-- Heroicon name: outline/emoji-happy -->
                                    <svg class="h-24 w-24" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" 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"></path>
                                    </svg>
                                </div>
                                <h3 class="text-lg leading-6 font-medium text-gray-900 px-3 mt-4 text-center">
                                    {{ __('Thanks') }}
                                </h3>
                                <p class="p-3 text-center">
                                    {{ __('Thank you for your feedback, it was saved successfully.') }}
                                </p>
                            </div>
                        </div>
                        <div x-show="!send" class="mt-6 relative flex-1 flex flex-col justify-between px-4 sm:px-6">
                            <div class="px-4 divide-y divide-gray-200 sm:px-6">
                                <fieldset class="space-y-2 my-4">
                                    <x-jet-label for="feedback_type">
                                        {{ __('Type of feedback') }}
                                    </x-jet-label>
                                    <div class="space-y-5">
                                        @foreach ($ticket_types as $ticket_type)
                                        <div>
                                            <div class="relative flex items-start">
                                                <div class="absolute flex items-center h-5">
                                                    <x-radio-button wire:model="ticket_type" @click="isQuestion = false" id="{{ $ticket_type->id }}" aria-describedby="{{ $ticket_type->id }}_description" value="{{ $ticket_type->id }}" class="h-4 w-4 transition duration-150 ease-in-out" />
                                                </div>
                                                <div class="pl-7 text-sm leading-5">
                                                    <x-jet-label for="{{ $ticket_type->id }}_title">
                                                        {{ $ticket_type->title }}
                                                    </x-jet-label>
                                                    <p id="{{ $ticket_type->id }}_description" class="text-gray-500">
                                                        {{ $ticket_type->description }}
                                                    </p>
                                                </div>
                                            </div>
                                        </div>
                                        @endforeach
                                    </div>
                                    <x-input-error for="ticket_type" />
                                </fieldset>
                                <div class="space-y-6 pt-6 pb-5">
                                    <div class="space-y-1" x-show="isQuestion">
                                        <x-jet-label for="subject">{{ __('Subject') }}</x-jet-label>
                                        <x-jet-input wire:model="subject" id="subject" class="block mt-1 w-full" type="text" name="subject" aria-describedby="subject" />
                                        <x-input-error for="description" />
                                    </div>
                                    <div class="space-y-1">
                                        <x-jet-label for="description">
                                            {{ __('Feedback') }}
                                        </x-jet-label>
                                        <x-textarea wire:model="description" id="description" rows="4" class="block mt-1 w-full"></x-textarea>
                                        <x-input-error for="description" />
                                    </div>
                                    <div class="space-y-1" x-show="!isQuestion">
                                        <div class="flex justify-between">
                                            <x-jet-label for="email_optional">{{ __('E-mail address') }}</x-jet-label>
                                            <span id="email_optional" class="font-normal text-sm leading-5 text-gray-500">
                                                {{ __('optional') }}
                                            </span>
                                        </div>
                                        <x-jet-input wire:model="email_optional" id="email_optional" class="block mt-1 w-full" type="email" name="email_optional" aria-describedby="email_optional" />
                                    </div>
                                    <div class="space-y-1" x-show="!isQuestion">
                                        <label for="data_protection" class="flex items-center">
                                            <x-jet-checkbox wire:model="data_protection" id="data_protection" name="data_protection" />
                                            <span class="ml-2 text-sm text-gray-600">{{ __('I have read the privacy policy and accept it.') }}</span>
                                        </label>
                                    </div>
                                </div>
                                <div class="space-y-4 pt-4 pb-6" x-show="!isQuestion">
                                    <div class="text-sm leading-5" x-data="{extra: false}">
                                        <a href="#" x-on:click.prevent="extra = !extra" class="group space-x-2 inline-flex items-center text-gray-500 hover:text-gray-900 transition ease-in-out duration-150">
                                            <svg class="h-5 w-5 text-gray-400 group-hover:text-gray-500 transition ease-in-out duration-150" viewBox="0 0 20 20" fill="currentColor">
                                                <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"></path>
                                            </svg>
                                            <span>
                                                {{ __('Why should you provide your email address?') }}
                                            </span>
                                        </a>
                                        <div x-show.transition="extra">
                                            <p class="ml-7">
                                                {{ __('If you include your email address, we will give you feedback on your feedback. We will never use your email address for any other purpose.') }}
                                            </p>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div x-show="!send" class="flex-shrink-0 px-4 py-4 space-x-4 flex justify-end">
                            <span class="inline-flex rounded-md shadow-sm">
                                <x-jet-secondary-button @click="isOpen = false">
                                    {{ __('cancel') }}
                                </x-jet-secondary-button>
                            </span>
                            <span class="inline-flex rounded-md shadow-sm">
                                <x-jet-button wire:click="send">
                                    {{ __('send') }}
                                </x-jet-button>
                            </span>
                        </div>
                        <div x-show="send" class="flex-shrink-0 px-4 py-4 space-x-4 flex justify-end">
                            <span class="inline-flex rounded-md shadow-sm">
                                <x-jet-secondary-button @click="isOpen = false">
                                    {{ __('close') }}
                                </x-jet-secondary-button>
                            </span>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </div>
</div>

Логика серверной части Livewire

      <?php

namespace App\Http\Livewire\Tickets;

use App\Models\Ticket;
use App\Rules\SpamFree;
use Livewire\Component;

class CreateTicketSlideOver extends Component
{
    public $ticket_type;

    public $subject;

    public $description;

    public $email_optional;

    public $data_protection = false;

    public $currentPage;

    public function mount()
    {
        $this->currentPage = url()->current();
    }

    public function send()
    {
        $this->validate([
            'ticket_type' => 'required',
            'subject' => ['required', new SpamFree],
            'description' => ['required', new SpamFree],
            'email_optional' => ['nullable', 'email'],
            'data_protection' => 'accepted',
        ]);

        Ticket::create([
            'user_id' => auth()->id(),
            'ticket_type' => $this->ticket_type_id,
            'slug' => $this->subject,
            'subject' => $this->subject,
            'description' => $this->body,
            'email' => $this->email,
            'url' => $this->currentPage,
        ]);


        $this->emitSelf('change-send');
    }

    public function render()
    {
        return view('tickets.create-ticket-slide-over');
    }
}

Перенос базы данных для заявки

      Schema::create('tickets', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id');
            $table->foreignId('ticket_type_id');
            $table->string('slug')->unique();
            $table->string('title');
            $table->text('body');
            $table->string('email')->nullable();
            $table->string('url')->nullable();
            $table->boolean('locked')->default(false);
            $table->unsignedInteger('visits')->default(0);
            $table->timestamps();
        });

0 ответов

Другие вопросы по тегам