Skip to content

Commit

Permalink
Custom Form Create and Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Xinecraft committed Dec 24, 2023
1 parent 9c74b28 commit 8c5ec09
Show file tree
Hide file tree
Showing 14 changed files with 994 additions and 492 deletions.
24 changes: 24 additions & 0 deletions app/Enums/CustomFormStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace App\Enums;

use BenSampo\Enum\Enum;

final class CustomFormStatus extends Enum
{
const DRAFT = 'draft';

const ACTIVE = 'active';

const DISABLED = 'disabled';

const ARCHIVED = 'archived';

public function toArray(): mixed
{
return [
'key' => $this->key,
'value' => $this->value,
];
}
}
64 changes: 48 additions & 16 deletions app/Http/Controllers/Admin/CustomFormController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\CreateCustomFormRequest;
use App\Http\Requests\UpdateCustomFormRequest;
use App\Models\CustomForm;
use App\Queries\Filters\FilterMultipleFields;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Spatie\QueryBuilder\AllowedFilter;
use Spatie\QueryBuilder\QueryBuilder;
Expand All @@ -27,14 +28,14 @@ public function index()
'title',
'slug',
'status',
'is_only_auth',
'is_only_staff',
'can_create_submission',
'require_restricted_permission_to_view_submission',
'is_notify_staff_on_submission',
'created_at',
'created_by',
AllowedFilter::custom('q', new FilterMultipleFields(['id', 'title', 'slug', 'description'])),
])
->allowedSorts(['id', 'title', 'slug', 'status', 'is_only_auth', 'is_only_staff', 'is_notify_staff_on_submission', 'created_at'])
->allowedSorts(['id', 'title', 'slug', 'status', 'can_create_submission', 'require_restricted_permission_to_view_submission', 'is_notify_staff_on_submission', 'created_at'])
->defaultSort('-id')
->paginate($perPage)
->withQueryString();
Expand All @@ -52,28 +53,59 @@ public function create()
return Inertia::render('Admin/CustomForm/CreateCustomForm');
}

public function store(Request $request)
public function store(CreateCustomFormRequest $request)
{
//
}
CustomForm::create([
'title' => $request->title,
'slug' => $request->slug,
'description' => $request->description,
'status' => $request->status,
'can_create_submission' => $request->can_create_submission,
'require_restricted_permission_to_view_submission' => $request->require_restricted_permission_to_view_submission,
'is_notify_staff_on_submission' => $request->is_notify_staff_on_submission,
'fields' => $request->fields,
'created_by' => $request->user()->id,
]);

public function show(string $id)
{
//
return redirect()->route('admin.custom-form.index')
->with(['toast' => ['type' => 'success', 'title' => __('Created Successfully'), 'body' => __('Custom Form is created successfully')]]);
}

public function edit(string $id)
public function edit(CustomForm $customForm)
{
//
$this->authorize('update', $customForm);

return Inertia::render('Admin/CustomForm/EditCustomForm', [
'customForm' => $customForm,
]);
}

public function update(Request $request, string $id)
public function update(UpdateCustomFormRequest $request, CustomForm $customForm)
{
//
$this->authorize('update', $customForm);

$customForm->title = $request->title;
$customForm->slug = $request->slug;
$customForm->description = $request->description;
$customForm->status = $request->status;
$customForm->can_create_submission = $request->can_create_submission;
$customForm->require_restricted_permission_to_view_submission = $request->require_restricted_permission_to_view_submission;
$customForm->is_notify_staff_on_submission = $request->is_notify_staff_on_submission;
$customForm->fields = $request->fields;
$customForm->updated_by = $request->user()->id;
$customForm->save();

return redirect()->back()
->with(['toast' => ['type' => 'success', 'title' => __('Updated Successfully'), 'body' => __('Custom Form updated successfully')]]);
}

public function destroy(string $id)
public function destroy(CustomForm $customForm)
{
//
$this->authorize('delete', $customForm);

$customForm->delete();

return redirect()->route('admin.custom-form.index')
->with(['toast' => ['type' => 'success', 'title' => __('Deleted Successfully'), 'body' => __('Custom Form has been deleted permanently')]]);
}
}
48 changes: 48 additions & 0 deletions app/Http/Requests/CreateCustomFormRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace App\Http\Requests;

use App\Enums\CustomFormStatus;
use App\Models\CustomForm;
use BenSampo\Enum\Rules\EnumValue;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;

class CreateCustomFormRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return Gate::allows('create', CustomForm::class);
}

/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
$inputTypes = config('constants.custom_form_input_types');

return [
'title' => 'required|string|max:255',
'slug' => 'required|alpha_dash|max:255|unique:custom_forms,slug',
'description' => 'nullable|string|max:50000',
'status' => ['required', new EnumValue(CustomFormStatus::class)],
'can_create_submission' => 'required|string|in:anyone,auth,staff',
'require_restricted_permission_to_view_submission' => 'required|boolean',
'is_notify_staff_on_submission' => 'required|boolean',
'fields' => 'required|array',
'fields.*.type' => 'required|string|in:'.implode(',', $inputTypes),
'fields.*.label' => 'required|string|max:255',
'fields.*.name' => 'required|string|alpha_dash|max:100|distinct:ignore_case',
'fields.*.placeholder' => 'sometimes|nullable|string|max:255',
'fields.*.help' => 'sometimes|nullable|string|max:255',
'fields.*.validation' => 'sometimes|nullable|string|max:255',
'fields.*.options' => 'sometimes|nullable|string',
];
}
}
52 changes: 52 additions & 0 deletions app/Http/Requests/UpdateCustomFormRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace App\Http\Requests;

use App\Enums\CustomFormStatus;
use BenSampo\Enum\Rules\EnumValue;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class UpdateCustomFormRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
$inputTypes = config('constants.custom_form_input_types');

return [
'title' => 'required|string|max:255',
'slug' => [
'required',
'alpha_dash',
'max:255',
Rule::unique('custom_forms')->ignore($this->route('customForm')),
],
'description' => 'nullable|string|max:50000',
'status' => ['required', new EnumValue(CustomFormStatus::class)],
'can_create_submission' => 'required|string|in:anyone,auth,staff',
'require_restricted_permission_to_view_submission' => 'required|boolean',
'is_notify_staff_on_submission' => 'required|boolean',
'fields' => 'required|array',
'fields.*.type' => 'required|string|in:'.implode(',', $inputTypes),
'fields.*.label' => 'required|string|max:255',
'fields.*.name' => 'required|string|alpha_dash|max:100|distinct:ignore_case',
'fields.*.placeholder' => 'sometimes|nullable|string|max:255',
'fields.*.help' => 'sometimes|nullable|string|max:255',
'fields.*.validation' => 'sometimes|nullable|string|max:255',
'fields.*.options' => 'sometimes|nullable|string',
];
}
}
4 changes: 4 additions & 0 deletions app/Models/CustomForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Models;

use App\Enums\CustomFormStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class CustomForm extends BaseModel
Expand All @@ -10,5 +11,8 @@ class CustomForm extends BaseModel

protected $casts = [
'fields' => 'array',
'status' => CustomFormStatus::class,
'require_restricted_permission_to_view_submission' => 'boolean',
'is_notify_staff_on_submission' => 'boolean',
];
}
20 changes: 20 additions & 0 deletions config/constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,24 @@
// Total Money if there is Vault
'$total_money__server_{id}' => 'The total amount of money the player has (in Vault), on server with id {id}. Eg: $total_money__server_1',
],

// Available input types for custom form
'custom_form_input_types' => [
'text',
'textarea',
'select',
'multiselect',
'radio',
'checkbox',
'email',
'number',
'password',
'tel',
'url',
'week',
'month',
'time',
'date',
'datetime-local',
],
];
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ public function up(): void
{
Schema::create('custom_forms', function (Blueprint $table) {
$table->id();
$table->string('title')->unique();
$table->string('title');
$table->string('slug')->unique();
$table->longText('description')->nullable();
$table->string('status')->default('active'); // draft, active, disabled, archived

$table->boolean('is_only_auth')->default(false); // only authenticated user can view & submit.
$table->boolean('is_only_staff')->default(false); // only staff can view & submit.
$table->string('can_create_submission')->default('anyone'); // anyone -> anyone, "auth" -> only authenticated users, "staff" -> only staff
$table->boolean('require_restricted_permission_to_view_submission')->default(false); // Only staff with view restricted_custom_form_submission permission can view submission for this form.
$table->boolean('is_notify_staff_on_submission')->default(false); // notify staff (with view access) when new submission is made.

$table->json('fields')->nullable();
Expand Down
1 change: 1 addition & 0 deletions database/seeders/PermissionSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public function run()
Permission::findOrCreate('update custom_forms');
Permission::findOrCreate('delete custom_forms');
Permission::findOrCreate('read custom_form_submissions');
Permission::findOrCreate('read restricted_custom_form_submissions');
Permission::findOrCreate('delete custom_form_submissions');

Permission::findOrCreate('view pulse_admin_dashboard');
Expand Down
30 changes: 30 additions & 0 deletions resources/js/Composables/useFormKit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export function useFormKit() {
const generateSchemaFromFieldsArray = (fields) => {
const generated = fields.map((field) => {
let f = {
$formkit: field.type == 'multiselect' ? 'select' : field.type,
label: field.label,
name:
field.name ?? field.label.toLowerCase().replace(/ /g, '_'),
help: field.help ?? undefined,
validation: field.validation ?? undefined,
placeholder: field.placeholder ?? undefined,
multiple: field.type == 'multiselect' ? true : undefined,
};

if (
field.type === 'select' ||
field.type === 'multiselect' ||
field.type === 'radio'
) {
f.options = field.options?.split(',') ?? [];
}
return f;
});
return generated;
};

return {
generateSchemaFromFieldsArray,
};
}
36 changes: 18 additions & 18 deletions resources/js/Jetstream/DialogModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,24 @@ const close = () => {
</script>

<template>
<Modal
:show="show"
:max-width="maxWidth"
:closeable="closeable"
@close="close"
>
<div class="px-6 py-4">
<div class="text-lg">
<slot name="title" />
</div>
<Modal
:show="show"
:max-width="maxWidth"
:closeable="closeable"
@close="close"
>
<div class="px-6 py-4 dark:bg-gray-800 dark:text-gray-300">
<div class="text-lg">
<slot name="title" />
</div>

<div class="mt-4">
<slot name="content" />
</div>
</div>
<div class="mt-4">
<slot name="content" />
</div>
</div>

<div class="flex flex-row justify-end px-6 py-4 bg-gray-100 text-right">
<slot name="footer" />
</div>
</Modal>
<div class="flex flex-row justify-end px-6 py-4 bg-gray-100 dark:bg-gray-800 text-right">
<slot name="footer" />
</div>
</Modal>
</template>
Loading

0 comments on commit 8c5ec09

Please sign in to comment.