Sorry, Larry, but what you suggested didn't work.
AppServiceProvider.php
// share flash messages
Inertia::share([
'flash' => function () {
return [
'message' => Session::get('message'),
'type' => Session::get('type'),
];
},
]);
Flash Component:
<template>
<div v-if="message">
<div v-if="type === 'success'" class="alert alert-success">
{{ message }}
</div>
<div v-if="type === 'error'" class="alert alert-error">
{{ message }}
</div>
</div>
</template>
<script>
defineProps(['message', 'type'])
</script>
Controller:
/**
* Store a user's newly created character resource in storage.
*
* @param StoreCharacterRequest $request user submitted form response
*
* @return Response|RedirectResponse redirect response on successful creation,
* otherwise inertia response on max characters reached
*/
public function store(StoreCharacterRequest $request): Response|RedirectResponse
{
// get the current player's characters count
$count = $this->countCharacter(auth()->user()->id);
// if the play is already at max characters
if ($count >= config("characters.max_allowed")) {
// display an error instead
return inertia('Characters/MaxCharacters');
}
// retrieve only the name and active status from the request
$validated = $request->safe()->only(['name', 'active']);
// if the player already has a character
if($count) {
// if the active checkbox was ticked
if($validated['active']) {
// get the player's active character if any
$character = Character::where('user_id', auth()->user()->id)
->where('active', 1)
->first(['id', 'active']);
// set the current one as not active
$character->update(['active' => 0]);
// and save the changes to the database
$character->save();
}
// otherwise this is the player's 1st character
} else {
// so mark the character as active
$validated['active'] = 1;
}
// get the first rank
$rank = Rank::where('min_xp', '<=', 1)
->first('id');
// and create the players character
Character::create([
'name' => $validated['name'],
'user_id' => auth()->user()->id,
'rank_id' => $rank->id,
'active' => $validated['active'],
]);
// then redirect to the characters index
return redirect('characters')->with(
'message', 'Character created successfully'
)->with(
'type', 'success'
);
Page:
<template>
<AppLayout title="My Characters">
<div class="grid row mt-5">
<div class="col-span-6 m-auto">
<div class="block max-w-sm p-6 bg-white border border-gray-200 rounded-lg shadow hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700">
<FlashMessage :message="$page.props.flash.message" :type="$page.props.flash.type"></FlashMessage>
<h1 class="text-center mb-3">
<i aria-hidden="true"></i> Characters
</h1>
<div v-if="characters.length === 0">
<p>You have no characters, why not create a new character?</p>
<Link :href="route('characters.create')" class="inline-block border border-blue-500 rounded py-1 px-3 bg-blue-500 text-white" role="link" title="Create a new character">Create a new character</Link>
</div>
<table v-else class="table-auto border-spacing-2 text-center">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Active</th>
<th scope="col">Options</th>
</tr>
</thead>
<tbody>
<tr v-for="character in characters" :key="character.id">
<th scope="row">{{ character.name }}</th>
<td><span v-if="character.active">X</span></td>
<td>
<Link :href="route('characters.show', {character: character})" class="text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500">Show</Link>
<Link v-if="!character.active" @click="switchCharacter(character.id)" class="text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500">Make active</Link>
<Link v-if="!character.active" @click="deleteCharacter(character.id)" class="text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500">Delete</Link>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</AppLayout>
</template>
<script setup>
import AppLayout from "@/Layouts/AppLayout.vue";
import {Link} from "@inertiajs/vue3";
import Swal from "sweetalert2";
defineProps(['characters']);
const switchCharacter = (characterId) => {
fetch(`/characters/${characterId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({})
})
.then(response => {
if (response.ok) {
// Handle success, maybe update the UI
Swal.fire({
title: 'Info!',
text: 'Character switched successfully!',
icon: 'success',
confirmButtonText: 'Ok'})
.then(() => {
window.location.reload(); // Reload the page to reflect changes
})
} else {
// Handle error
Swal.fire({
title: 'Error!',
text: 'Failed to switch character.',
icon: 'error',
confirmButtonText: 'Ok'})
}
})
.catch(error => {
console.error('Error:', error);
Swal.fire({
title: 'Error!',
text: 'Failed to switch character.',
icon: 'error',
confirmButtonText: 'Ok'})
});
}
const deleteCharacter = (characterId) => {
Swal.fire({
title: 'Warning',
text: 'Do you wish to delete the character?',
icon: 'warning',
showCancelButton: true,
cancelButtonColor: '#ff0000',
confirmButtonText: 'Delete',
confirmButtonColor: '#7066e0',
reverseButtons: true,
focusConfirm: false
}).then((result) => {
if (result.isConfirmed) {
fetch(`/characters/${characterId}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({})
})
.then(response => {
if (response.ok) {
// Handle success, maybe update the UI
Swal.fire({
title: 'Info!',
text: 'Character deleted successfully!',
icon: 'success',
confirmButtonText: 'Ok'})
.then(() => {
window.location.reload(); // Reload the page to reflect changes
})
} else {
// Handle error
Swal.fire({
title: 'Error!',
text: 'Failed to delete character.',
icon: 'error',
confirmButtonText: 'Ok'})
}
})
.catch(error => {
Swal.fire({
title: 'Error!',
text: 'Failed to delete character.',
icon: 'error',
confirmButtonText: 'Ok'})
console.error('Error:', error);
});
} else {
Swal.fire({
title: 'Info!',
text: 'Character deletion cancelled successfully.',
icon: 'info',
confirmButtonText: 'Ok'})
}
});
}
</script>