Забацал фичу с отзывами

This commit is contained in:
Dhaverd 2024-06-03 17:46:20 +08:00
parent 5c79d92fa1
commit c6c6ddeb3e
9 changed files with 206 additions and 36 deletions

View File

@ -0,0 +1,19 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\Rating;
class RatingController extends Controller
{
public function index(Request $request)
{
$rating = new Rating;
$rating->rate = $request->rate;
$rating->comment = $request->comment;
$rating->save();
return ['code' => $rating->save() ? 200 : 500];
}
}

19
app/Models/Rating.php Normal file
View File

@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
class Rating extends Model
{
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'rating';
}

View File

@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('rating', function (Blueprint $table) {
$table->id();
$table->integer('rate')->nullable();
$table->text('comment')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('rating');
}
};

View File

@ -0,0 +1,10 @@
.box-gradient {
border: 10px solid transparent;
background: linear-gradient(
#ffffff,
#ffffff) padding-box,
linear-gradient(45deg,
#FF52E5,
#F6D242) border-box;
border-radius: 14px;
}

View File

@ -3,37 +3,52 @@
<p class="text-xl-h3 text-lg-h3 text-md-h4 text-sm-h4 text-h5 ma-5">Расписание стримов</p> <p class="text-xl-h3 text-lg-h3 text-md-h4 text-sm-h4 text-h5 ma-5">Расписание стримов</p>
<v-skeleton-loader v-if="fetching" type="text" /> <v-skeleton-loader v-if="fetching" type="text" />
<p v-else class="ma-5 text-xl-h3 text-lg-h3 text-md-h4 text-sm-h4 text-h5"> {{ parseDate(dates[0].current_date) }} - {{ parseDate(dates[1].current_date) }}</p> <p v-else class="ma-5 text-xl-h3 text-lg-h3 text-md-h4 text-sm-h4 text-h5"> {{ parseDate(dates[0].current_date) }} - {{ parseDate(dates[1].current_date) }}</p>
<ScheduleTable/> <ScheduleTable :is-wide="isWide"/>
<p class="text-xl-h3 text-lg-h3 text-md-h4 text-sm-h4 text-h5 ma-5">Ссылочки</p> <p class="text-xl-h3 text-lg-h3 text-md-h4 text-sm-h4 text-h5 ma-5">Ссылочки</p>
<Links/> <Links :is-wide="isWide"/>
<AdditionalButtons :is-wide="isWide"/>
</v-sheet> </v-sheet>
</template> </template>
<script> <script>
import ScheduleTable from "./Schedule/ScheduleTable.vue"; import ScheduleTable from "./Schedule/ScheduleTable.vue";
import Links from "./Schedule/Links.vue"; import Links from "./Schedule/Links.vue";
import AdditionalButtons from "./Schedule/AdditionalButtons.vue";
import {ref} from "vue"; import {ref} from "vue";
import {useScheduleStore} from '../stores/schedule.js'; import {useScheduleStore} from '../stores/schedule.js';
export default { export default {
name: "Schedule", name: "Schedule",
components: {Links, ScheduleTable}, components: {AdditionalButtons, Links, ScheduleTable},
data: () => ({ data: () => ({
dates: ref(), dates: ref(),
scheduleStore: useScheduleStore(), scheduleStore: useScheduleStore(),
fetching: true fetching: true,
windowHeight: document.documentElement.clientHeight,
windowWidth: document.documentElement.clientWidth,
isWide: window.innerWidth >= 460
}), }),
methods: { methods: {
parseDate(date){ parseDate(date){
let dateArr = date.split("-"); let dateArr = date.split("-");
return dateArr[2] + "." + dateArr[1]; return dateArr[2] + "." + dateArr[1];
},
myEventHandler(e) {
this.windowHeight = document.documentElement.clientHeight;
this.windowWidth = document.documentElement.clientWidth;
this.isWide = this.windowWidth >= 460;
} }
}, },
created() {
window.addEventListener("resize", this.myEventHandler);
},
mounted() { mounted() {
this.scheduleStore.getDates().then(()=>{ this.scheduleStore.getDates().then(()=>{
this.dates = this.scheduleStore.dates; this.dates = this.scheduleStore.dates;
this.fetching = false; this.fetching = false;
}); });
this.myEventHandler();
window.addEventListener("resize", this.myEventHandler, { passive: true });
} }
} }
</script> </script>

View File

@ -0,0 +1,101 @@
<script>
import Links from "./Links.vue";
import ScheduleTable from "./ScheduleTable.vue";
import {ref} from "vue";
import {useScheduleStore} from "../../stores/schedule.js";
export default {
name: "AdditionalButtons",
data: () => ({
showModal: ref(false),
afterModal: ref(false),
afterModalText: '',
rating: 0,
comment: ''
}),
props: {
isWide: Boolean
},
methods:{
onShowModal(){
this.showModal = !this.showModal;
if (!this.showModal){
this.rating = 0;
this.comment = '';
}
},
onShowAfterModal(){
this.afterModal = !this.afterModal;
},
sendRating(){
axios.post(
'/api/v1/rating',
{
rate: this.rating,
comment: this.comment
}
).then((responce)=>{
this.onShowModal();
console.log(responce.data['code']);
if (responce.data['code'] === 200){
this.afterModalText = 'Спасибо за отзыв!';
} else {
this.afterModalText = 'Ошибка: Отзыв не отправился :(';
}
this.onShowAfterModal();
});
}
}
}
</script>
<template>
<div class="w-100 d-flex justify-space-evenly" :class="isWide ? '' : 'flex-column'">
<v-btn
class="box-gradient pt-2 pb-2 ma-5 h-auto"
text="Кинуть копеечку"
href="https://www.donationalerts.com/r/dhaverd"
target="_blank"
/>
<v-btn
class="box-gradient pt-2 pb-2 ma-5 h-auto"
text="Оставить отзыв"
@click="onShowModal"
/>
</div>
<v-dialog v-model="showModal" class="align-center" :class="isWide ? 'w-50' : 'w-100 h-100'">
<v-sheet class="mt-5 mb-5 pa-5 h-auto rounded-lg d-flex flex-column">
<div class="w-100 d-flex justify-end">
<v-btn icon="mdi-window-close" elevation="0" @click="onShowModal"/>
</div>
<v-label class="text-xl-h6">Оцените канал:</v-label>
<v-rating v-model="rating" active-color="orange-lighten-1">
sss
</v-rating>
<v-label class="text-xl-h6 mb-2">Оставьте отзыв:</v-label>
<v-textarea v-model="comment" clearable variant="outlined" label="Что можно улучшить?"/>
<div class="d-flex justify-center">
<v-btn class="box-gradient pt-2 pb-2 w-auto h-auto" @click="sendRating">Отправить</v-btn>
</div>
</v-sheet>
</v-dialog>
<v-dialog v-model="afterModal" class="align-center" :class="isWide ? 'w-50' : 'w-100 h-100'">
<v-sheet class="mt-5 mb-5 pa-5 h-auto rounded-lg d-flex flex-column">
<div class="w-100 d-flex justify-end">
<v-btn icon="mdi-window-close" elevation="0" @click="onShowAfterModal"/>
</div>
<v-label class="text-xl-h6">{{afterModalText}}</v-label>
</v-sheet>
</v-dialog>
</template>
<style scoped>
.v-dialog {
align-items: center;
justify-content: center;
margin: auto;
}
.v-label {
color: #000000;
}
</style>

View File

@ -7,28 +7,16 @@
data: () => ({ data: () => ({
links: ref(), links: ref(),
fetching: true, fetching: true,
scheduleStore: useScheduleStore(), scheduleStore: useScheduleStore()
windowHeight: document.documentElement.clientHeight,
windowWidth: document.documentElement.clientWidth,
isWide: window.innerWidth >= 460
}), }),
props: {
isWide: Boolean
},
mounted() { mounted() {
this.scheduleStore.getLinks().then(()=>{ this.scheduleStore.getLinks().then(()=>{
this.links = this.scheduleStore.links; this.links = this.scheduleStore.links;
this.fetching = false; this.fetching = false;
}); });
this.myEventHandler();
window.addEventListener("resize", this.myEventHandler, { passive: true });
},
created() {
window.addEventListener("resize", this.myEventHandler);
},
methods: {
myEventHandler(e) {
this.windowHeight = document.documentElement.clientHeight;
this.windowWidth = document.documentElement.clientWidth;
this.isWide = this.windowWidth >= 460;
}
} }
} }
</script> </script>
@ -48,20 +36,5 @@
</template> </template>
<style scoped> <style scoped>
.bg-gradient-noh {
background: linear-gradient(-45deg, #f103b0, #f0a068, #4fdbfeff);
background-size: 200% 200%;
animation: gradient 15s ease infinite;
}
.box-gradient {
border: 10px solid transparent;
background: linear-gradient(
#ffffff,
#ffffff) padding-box,
linear-gradient(45deg,
#FF52E5,
#F6D242) border-box;
border-radius: 14px;
}
</style> </style>

View File

@ -9,6 +9,9 @@
scheduleStore: useScheduleStore(), scheduleStore: useScheduleStore(),
fetching: true fetching: true
}), }),
props: {
isWide: Boolean
},
methods: { methods: {
parseDate(date){ parseDate(date){
let dateArr = date.split("-"); let dateArr = date.split("-");
@ -27,7 +30,7 @@
<template> <template>
<div class="w-100 d-flex justify-center"> <div class="w-100 d-flex justify-center">
<v-skeleton-loader v-if="fetching" type="table"/> <v-skeleton-loader v-if="fetching" type="table"/>
<v-table v-else class="text-xl-h5 text-lg-h5 text-md-h5 text-sm-h5 text-body-2 w-66"> <v-table v-else class="text-xl-h5 text-lg-h5 text-md-h5 text-sm-h5 text-body-2" :class="isWide ? 'w-66' : 'w-100'">
<tbody> <tbody>
<tr v-for="schedule in schedules"> <tr v-for="schedule in schedules">
<td>{{ parseDate(schedule.current_date) }} {{ schedule.weekday_name }} {{ schedule.stream_time }}</td> <td>{{ parseDate(schedule.current_date) }} {{ schedule.weekday_name }} {{ schedule.stream_time }}</td>

View File

@ -19,3 +19,4 @@ Route::get('/links', 'App\Http\Controllers\LinksController@index')->name('links'
Route::get('/schedules', 'App\Http\Controllers\SchedulesController@index')->name('schedules'); Route::get('/schedules', 'App\Http\Controllers\SchedulesController@index')->name('schedules');
Route::get('/dates', 'App\Http\Controllers\SchedulesController@mmDate')->name('dates'); Route::get('/dates', 'App\Http\Controllers\SchedulesController@mmDate')->name('dates');
Route::get('/phrases', 'App\Http\Controllers\BasyaPhrasesController@index')->name('phrases'); Route::get('/phrases', 'App\Http\Controllers\BasyaPhrasesController@index')->name('phrases');
Route::post('/rating', 'App\Http\Controllers\RatingController@index')->name('rating');