Сделал основную часть брони

This commit is contained in:
p.belezov 2025-01-09 17:08:44 +08:00
parent 590fa5ed3f
commit 73f77d58f8
7 changed files with 116 additions and 16 deletions

View File

@ -84,4 +84,19 @@ class WishesController extends Controller
Wish::destroy($request->get('id'));
return response()->json(null, 204);
}
public function book(Request $request)
{
$request->validate([
'id' => 'required|exists:wishes,id',
'user_id' => 'required|exists:users,id'
]);
$wish = Wish::find($request->get('id'));
if (isset($wish->book_user_id)){
return response()->json(["error" => 'Уже забронировано' ], 409);
}
$wish->book_user_id = $request->get('user_id');
$wish->save();
return response()->json($wish, 200);
}
}

View File

@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\Model;
class Wish extends Model
{
use HasFactory;
protected $fillable = ['user_id', 'name', 'price', 'url'];
protected $fillable = ['user_id', 'name', 'price', 'url', 'book_user_id'];
public function user(){
return $this->belongsTo(User::class);

View File

@ -84,5 +84,25 @@ export const useWishStore = defineStore('wish', {
});
return result;
},
async book(id, user_id, token){
let result = null;
await axios.post(`/api/wish/book`,
{
id: id,
user_id: user_id
},
{
headers: {
Authorization: `Bearer ${token}`,
token: token
},
}
).then((response)=>{
result = response;
}).catch((error)=>{
result = error;
});
return result;
}
},
})

View File

@ -47,7 +47,9 @@ export default {
if (isLogged){
this.errorMessage = '';
this.errorMessageContainerStyle = 'display: none;';
this.$router.push('/');
// this.$router.push('/');
// console.log(window.location.href);
// window.location.replace(window.location.href);
} else {
this.errorMessage = 'Authentication error';
this.errorMessageContainerStyle = '';

View File

@ -13,11 +13,25 @@
<div v-else>
<a class="link-no-decor align-end" @click="showAuthDialog = true">Вход/Регистрация</a>
</div>
<v-dialog v-model="showAuthDialog">
<v-dialog v-model="showAuthDialog" class="w-66">
<v-card class="card-bg">
<v-card-title class="d-flex justify-end">
<v-icon @click="showAuthDialog = false" class="cursor-pointer" color="white" icon="mdi-close-thick"></v-icon>
</v-card-title>
<v-card-text class="w-100">
<v-tabs class="w-100" align-tabs="center" v-model="tab">
<v-tab :value="1">Вход</v-tab>
<v-tab :value="2">Регистрация</v-tab>
</v-tabs>
<v-tabs-window v-model="tab" class="w-100 h-auto">
<v-tabs-window-item :key="1" :value="1">
<v-container fluid class="d-flex align-center justify-center"><Login/></v-container>
</v-tabs-window-item>
<v-tabs-window-item :key="2" :value="2">
<v-container fluid class="d-flex align-center justify-center"><Registration/></v-container>
</v-tabs-window-item>
</v-tabs-window>
</v-card-text>
</v-card>
</v-dialog>
</v-card-title>
@ -33,18 +47,24 @@
import ShowWhishlist from "./PublicWishlist/ShowWhishlist.vue";
import {useUserStore} from "../store/user.js";
import { watch } from "vue";
import Login from "./Auth/Login.vue";
import Registration from "./Auth/Registration.vue";
export default {
name: "Public",
components: {ShowWhishlist},
components: {Registration, Login, ShowWhishlist},
data: ()=>({
isAuthenticated: false,
isWide: window.innerWidth >= 800,
userStore: useUserStore(),
showAuthDialog: false
showAuthDialog: false,
tab: null
}),
mounted() {
watch(this.userStore, (newStore, oldStore)=>{
this.isAuthenticated = newStore.user !== null && newStore.user !== undefined;
if (this.isAuthenticated){
this.showAuthDialog = false;
}
});
useUserStore().checkUser();
},

View File

@ -4,10 +4,13 @@ import { useUserStore } from "../../store/user.js";
import DeleteWish from "../Wishlist/DeleteWish.vue";
import CreateWish from "../Wishlist/CreateWish.vue";
import EditWish from "../Wishlist/EditWish.vue";
import {watch} from "vue";
export default {
name: "ShowWhishlist",
components: {EditWish, CreateWish, DeleteWish},
data: () => ({
isAuthenticated: false,
isSameUser: false,
wishes: [],
wishStore: useWishStore(),
userStore: useUserStore(),
@ -16,7 +19,10 @@ export default {
username: '',
bookConfirmationDialog: false,
bookItemId: '',
bookItemName: ''
bookItemName: '',
bookError: false,
bookErrorText: '',
bookLoading: false
}),
methods: {
bookDialog(id, name){
@ -26,14 +32,41 @@ export default {
},
closeBookDialog(){
this.bookConfirmationDialog = false;
},
book(){
this.bookLoading = true;
this.wishStore.book(this.bookItemId, this.userStore.user["id"], this.userStore.token).then((response)=>{
this.bookError = false;
if (response.request.status == 409){
this.bookErrorText = response.response.data.error;
this.bookError = true;
} else {
this.bookConfirmationDialog = false;
this.fetching = true;
let urlArray = window.location.href.split('/');
let user_id = urlArray[urlArray.length - 1];
this.wishStore.getUserWishes(user_id).then((res)=>{
this.wishes = res;
this.fetching = false;
});
}
this.bookLoading = false;
}).catch(()=>{
this.bookLoading = false;
});
}
},
mounted() {
let urlArray = window.location.href.split('/');
let user_id = urlArray[urlArray.length - 1];
watch(this.userStore, (newStore, oldStore)=>{
this.isAuthenticated = newStore.user !== null && newStore.user !== undefined;
if (newStore.user !== null && newStore.user !== undefined){
this.isSameUser = user_id == this.userStore.user['id'];
}
});
this.fetching = true;
this.userStore.getUsername(user_id).then((res)=>{
console.log(res);
this.username = res.data.username;
this.wishStore.getUserWishes(user_id).then((responce)=>{
this.wishes = responce;
@ -64,19 +97,26 @@ export default {
<td>{{ wish['price'] }}</td>
<td><a target="_blank" :href="wish['url']">{{ wish['url'] }}</a></td>
<td>
<v-btn v-if="wish['book_user'] === null" @click="bookDialog(wish['id'], wish['name'])">Забронировать</v-btn>
<span v-if="wish['book_user'] === null">
<v-btn v-if="isAuthenticated && !isSameUser" @click="bookDialog(wish['id'], wish['name'])">Забронировать</v-btn>
<span v-else>Нет</span>
</span>
<span v-else><v-icon color="green" icon="mdi-check-bold"></v-icon></span>
</td>
</tr>
</tbody>
<!-- TODO Сделать чек логина -->
<v-dialog v-model="bookConfirmationDialog" class="w-33">
<v-card class="card-bg">
<v-card-text>
<v-label style="text-wrap: auto;">Хотите забронировать {{ bookItemName }}?</v-label>
<div class="d-flex justify-center">
<v-btn class="mt-2 ml-2 mr-2">Да</v-btn>
<v-btn @click="closeBookDialog" class="mt-2 ml-2 mr-2">Нет</v-btn>
<div>
<v-label style="text-wrap: auto;">Хотите забронировать {{ bookItemName }}?</v-label>
<div class="d-flex justify-center">
<v-btn @click="book" :loading="bookLoading" class="mt-2 ml-2 mr-2">Да</v-btn>
<v-btn @click="closeBookDialog" class="mt-2 ml-2 mr-2">Нет</v-btn>
</div>
</div>
<div>
</div>
</v-card-text>
</v-card>
@ -91,18 +131,20 @@ export default {
<div class="d-flex flex-column">
<v-label class="mr-3 ml-5 text-body-1">Цена: {{ wish['price'] }}</v-label>
<v-label class="mr-3 ml-5 text-body-1">Забронировано:&nbsp;
<span v-if="wish['book_user'] === null" class="smth" @click="bookDialog(wish['id'], wish['name'])">Нет</span>
<span v-if="wish['book_user'] === null">
<v-btn v-if="isAuthenticated && !isSameUser" @click="bookDialog(wish['id'], wish['name'])">Забронировать</v-btn>
<span v-else>Нет</span>
</span>
<span v-else> Да</span>
</v-label>
</div>
</div>
<!-- TODO Сделать чек логина -->
<v-dialog v-model="bookConfirmationDialog">
<v-card class="card-bg">
<v-card-text>
<v-label style="text-wrap: auto;">Хотите забронировать {{ bookItemName }}?</v-label>
<div class="d-flex justify-center">
<v-btn class="mt-2 ml-2 mr-2">Да</v-btn>
<v-btn @click="book" :loading="bookLoading" class="mt-2 ml-2 mr-2">Да</v-btn>
<v-btn @click="closeBookDialog" class="mt-2 ml-2 mr-2">Нет</v-btn>
</div>
</v-card-text>

View File

@ -38,5 +38,6 @@ Route::group(['prefix' => 'wish'], function () {
Route::post('update', [WishesController::class, 'update']);
Route::post('destroy', [WishesController::class, 'destroy']);
Route::get('by_id/{id}', [WishesController::class, 'getWishById']);
Route::post('book', [WishesController::class, 'book']);
});
});