forked from aslan/applicant-site
add feedback and status resources
This commit is contained in:
parent
c27ad2c05b
commit
a1ccaba32a
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\admin;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\admin\StoreFeedbackRequest;
|
||||||
|
use App\Http\Requests\admin\UpdateFeedbackRequest;
|
||||||
|
use App\Models\Feedback;
|
||||||
|
use App\Models\FeedbackStatus;
|
||||||
|
|
||||||
|
class FeedbackController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$feedbacks = Feedback::all();
|
||||||
|
return view('admin.feedback.index', compact('feedbacks'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(StoreFeedbackRequest $request)
|
||||||
|
{
|
||||||
|
$validated = $request->validated();
|
||||||
|
$feedback = new Feedback();
|
||||||
|
|
||||||
|
$feedback->contact = $validated['contact'];
|
||||||
|
$feedback->text = $validated['text'];
|
||||||
|
$feedback->status_id = $validated['status_id'];
|
||||||
|
$feedback->save();
|
||||||
|
|
||||||
|
return response()->json(["result" => "success"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(Feedback $feedback)
|
||||||
|
{
|
||||||
|
$feedbackStatuses = FeedbackStatus::pluck('name', 'id');
|
||||||
|
return view('admin.feedback.edit', compact('feedback', 'feedbackStatuses'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(UpdateFeedbackRequest $request, Feedback $feedback)
|
||||||
|
{
|
||||||
|
$validated = $request->validated();
|
||||||
|
|
||||||
|
$feedback->contact = $validated['contact'];
|
||||||
|
$feedback->text = $validated['text'];
|
||||||
|
$feedback->status_id = $validated['status_id'];
|
||||||
|
$feedback->save();
|
||||||
|
|
||||||
|
return redirect()->route('feedback.index');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\admin;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\admin\StoreFeedbackStatusRequest;
|
||||||
|
use App\Http\Requests\admin\UpdateFeedbackStatusRequest;
|
||||||
|
use App\Models\FeedbackStatus;
|
||||||
|
|
||||||
|
class FeedbackStatusController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$feedbackStatuses = FeedbackStatus::all();
|
||||||
|
return view('admin.feedback_statuses.index', compact('feedbackStatuses'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('admin.feedback_statuses.create');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(StoreFeedbackStatusRequest $request)
|
||||||
|
{
|
||||||
|
$validated = $request->validated();
|
||||||
|
$feedbackStatus = new FeedbackStatus();
|
||||||
|
$feedbackStatus->name = $validated['name'];
|
||||||
|
$feedbackStatus->save();
|
||||||
|
|
||||||
|
return redirect()->route('feedback_statuses.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(FeedbackStatus $feedbackStatus)
|
||||||
|
{
|
||||||
|
return view('admin.feedback_statuses.edit', compact('feedbackStatus'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(UpdateFeedbackStatusRequest $request, FeedbackStatus $feedbackStatus)
|
||||||
|
{
|
||||||
|
$validated = $request->validated();
|
||||||
|
$feedbackStatus->name = $validated['name'];
|
||||||
|
$feedbackStatus->save();
|
||||||
|
|
||||||
|
return redirect()->route('feedback_statuses.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy(FeedbackStatus $feedbackStatus)
|
||||||
|
{
|
||||||
|
if ($feedbackStatus->feedbacks()->exists()) {
|
||||||
|
return back();
|
||||||
|
}
|
||||||
|
$feedbackStatus->delete();
|
||||||
|
return redirect()->route('feedback_statuses.index');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\admin;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class StoreFeedbackRequest extends FormRequest
|
||||||
|
{
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'contact' => 'required|string|max:255',
|
||||||
|
'text' => 'string|nullable',
|
||||||
|
'status_id' => 'required|numeric|exists:feedback_statuses,id',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\admin;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class StoreFeedbackStatusRequest extends FormRequest
|
||||||
|
{
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => 'required|string|max:255',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\admin;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class UpdateFeedbackRequest extends FormRequest
|
||||||
|
{
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'contact' => 'required|string|max:255',
|
||||||
|
'text' => 'string|nullable',
|
||||||
|
'status_id' => 'required|numeric|exists:feedback_statuses,id',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\admin;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class UpdateFeedbackStatusRequest extends FormRequest
|
||||||
|
{
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => 'required|string|max:255',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class Feedback extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'id',
|
||||||
|
'contact',
|
||||||
|
'text',
|
||||||
|
'stats_id',
|
||||||
|
'created_at',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function status(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(FeedbackStatus::class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
|
class FeedbackStatus extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'created_at',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function feedbacks(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany('App\Models\Feedback', 'status_id');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
class FeedbackFactory extends Factory
|
||||||
|
{
|
||||||
|
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'contact' => fake()->email(),
|
||||||
|
'text' => fake()->text(),
|
||||||
|
'status_id' => 1,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
class FeedbackStatusFactory extends Factory
|
||||||
|
{
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => fake()->name(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?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('feedback_statuses', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('name', 255);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('feedback_statuses');
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?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('feedback', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('contact', 255);
|
||||||
|
$table->text('text');
|
||||||
|
$table->foreignId('status_id')->constrained('feedback_statuses');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('feedback');
|
||||||
|
}
|
||||||
|
};
|
|
@ -36,5 +36,10 @@ class DatabaseSeeder extends Seeder
|
||||||
AdmissionSeeder::class,
|
AdmissionSeeder::class,
|
||||||
DocumentSeeder::class,
|
DocumentSeeder::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->call([
|
||||||
|
FeedbackStatusSeeder::class,
|
||||||
|
FeedbackSeeder::class,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class FeedbackSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
DB::table('feedback')->insert([
|
||||||
|
[
|
||||||
|
'contact' => '79112223344',
|
||||||
|
'text' => 'Мое новое обращение',
|
||||||
|
'status_id' => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'contact' => 'example@example.com',
|
||||||
|
'text' => 'Мое новое обращение',
|
||||||
|
'status_id' => 1,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class FeedbackStatusSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
DB::table('feedback_statuses')->insert([
|
||||||
|
[
|
||||||
|
'name' => 'создано',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'в работе',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
@php use App\Helpers\PositionHelper; @endphp
|
||||||
|
@extends('layouts.admin_layout')
|
||||||
|
@section('content')
|
||||||
|
@auth()
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h1 class="">Изменить Статус обращения</h1>
|
||||||
|
{{ Form::open(['url' => route('feedback.update', $feedback), 'method' => 'PATCH', 'files'=>'true', 'class' => 'needs-validation', 'novalidate']) }}
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
{{ Form::label('contact', 'Контакт', ['data-bs-toggle' => "tooltip", 'data-bs-title' => __('tooltips.feedback.contact')]) }}
|
||||||
|
</div>
|
||||||
|
<div class="mt-1">
|
||||||
|
{{ Form::text('contact', $feedback->contact, ['class' => 'form-control', 'data-bs-toggle' => "tooltip", 'data-bs-title' => __('tooltips.feedback.contact'), 'required', 'readonly' => ""]) }}
|
||||||
|
</div>
|
||||||
|
<div class="text-danger">
|
||||||
|
@if ($errors->any())
|
||||||
|
{{ $errors->first('contact') }}
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
{{ Form::label('text', 'Текст', ['data-bs-toggle' => "tooltip", 'data-bs-title' => __('tooltips.feedback.text')]) }}
|
||||||
|
</div>
|
||||||
|
<div class="mt-1">
|
||||||
|
{{ Form::textarea('text', $feedback->text, ['class' => 'form-control', 'data-bs-toggle' => "tooltip", 'data-bs-title' => __('tooltips.feedback.text'), 'required', 'readonly' => ""]) }}
|
||||||
|
</div>
|
||||||
|
<div class="text-danger">
|
||||||
|
@if ($errors->any())
|
||||||
|
{{ $errors->first('text') }}
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
{{ Form::label('status_id', 'Статус обращения', ['data-bs-toggle' => "tooltip", 'data-bs-title' => __('tooltips.feedback.status_id')]) }}
|
||||||
|
</div>
|
||||||
|
<div class="mt-1">
|
||||||
|
{{ Form::select('status_id', $feedbackStatuses, $feedback->status_id, ['class' => 'form-control', 'data-bs-toggle' => "tooltip", 'data-bs-title' => __('tooltips.feedback.status_id'), 'required']) }}
|
||||||
|
</div>
|
||||||
|
<div class="text-danger">
|
||||||
|
@if ($errors->any())
|
||||||
|
{{ $errors->first('text') }}
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
{{ Form::submit('Изменить', ['class' => 'btn btn-primary']) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ Form::close() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endauth
|
||||||
|
@include('layouts.bootstrap_validation')
|
||||||
|
@endsection
|
|
@ -0,0 +1,35 @@
|
||||||
|
@extends('layouts.admin_layout')
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<h2>Обр. связь</h2>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<table class="table">
|
||||||
|
<thead class="border-b-2 border-solid border-black text-left" style="text-align: left">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Контакт</th>
|
||||||
|
<th scope="col">Текст</th>
|
||||||
|
<th scope="col">Статус</th>
|
||||||
|
<th scope="col">Создано</th>
|
||||||
|
<th scope="col">Действия</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($feedbacks as $feedback)
|
||||||
|
<tr class="">
|
||||||
|
<td>{{ $feedback->contact }}</a></td>
|
||||||
|
<td>{{ $feedback->text }}</a></td>
|
||||||
|
<td>{{ $feedback->status->name }}</a></td>
|
||||||
|
<td>{{ $feedback->created_at }}</a></td>
|
||||||
|
<td><a href="{{ route("feedback.edit", $feedback) }}"
|
||||||
|
class="btn btn-secondary">редактировать</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endsection
|
|
@ -0,0 +1,36 @@
|
||||||
|
@php use App\Helpers\PositionHelper; @endphp
|
||||||
|
@extends('layouts.admin_layout')
|
||||||
|
@section('content')
|
||||||
|
@auth()
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h1 class=""> Создать Статус</h1>
|
||||||
|
{{ Form::open(['url' => route('feedback_statuses.store'), 'method' => 'POST', 'files'=>'true', 'class' => 'needs-validation', 'novalidate']) }}
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
{{ Form::label('name', 'Название', ['data-bs-toggle' => "tooltip", 'data-bs-title' => __('tooltips.news.name')]) }}
|
||||||
|
<span class="text-danger">*</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-1">
|
||||||
|
{{ Form::text('name', '', ['class' => 'form-control', 'data-bs-toggle' => "tooltip", 'data-bs-title' => __('tooltips.news.name'), 'required']) }}
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
Поле "Название" обязательно!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-danger">
|
||||||
|
@if ($errors->any())
|
||||||
|
{{ $errors->first('name') }}
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
{{ Form::submit('Создать', ['class' => 'btn btn-primary']) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ Form::close() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endauth
|
||||||
|
@include('layouts.bootstrap_validation')
|
||||||
|
@endsection
|
|
@ -0,0 +1,36 @@
|
||||||
|
@php use App\Helpers\PositionHelper; @endphp
|
||||||
|
@extends('layouts.admin_layout')
|
||||||
|
@section('content')
|
||||||
|
@auth()
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h1 class="">Изменить Новость</h1>
|
||||||
|
{{ Form::open(['url' => route('feedback_statuses.update', $feedbackStatus), 'method' => 'PATCH', 'files'=>'true', 'class' => 'needs-validation', 'novalidate']) }}
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
{{ Form::label('name', 'Название', ['data-bs-toggle' => "tooltip", 'data-bs-title' => __('tooltips.news.name')]) }}
|
||||||
|
<span class="text-danger">*</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-1">
|
||||||
|
{{ Form::text('name', $feedbackStatus->name, ['class' => 'form-control', 'data-bs-toggle' => "tooltip", 'data-bs-title' => __('tooltips.news.name'), 'required']) }}
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
Поле "Название" обязательно!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-danger">
|
||||||
|
@if ($errors->any())
|
||||||
|
{{ $errors->first('name') }}
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
{{ Form::submit('Изменить', ['class' => 'btn btn-primary']) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ Form::close() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endauth
|
||||||
|
@include('layouts.bootstrap_validation')
|
||||||
|
@endsection
|
|
@ -0,0 +1,36 @@
|
||||||
|
@extends('layouts.admin_layout')
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<h2>Статусы</h2>
|
||||||
|
<br>
|
||||||
|
<a href="{{ route('feedback_statuses.create') }}" class="btn btn-primary">Создать Статус</a>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<table class="table">
|
||||||
|
<thead class="border-b-2 border-solid border-black text-left" style="text-align: left">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Название</th>
|
||||||
|
<th scope="col">Действия</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($feedbackStatuses as $status)
|
||||||
|
<tr class="">
|
||||||
|
<td>{{ $status->name }}</a></td>
|
||||||
|
<td><a href="{{ route("feedback_statuses.edit", $status) }}"
|
||||||
|
class="btn btn-secondary">редактировать</a>
|
||||||
|
<a rel="nofollow" data-method="delete" data-confirm="Вы действительно хотите удалить?"
|
||||||
|
href="{{ route('feedback_statuses.destroy', $status) }}"
|
||||||
|
class="btn btn-danger">
|
||||||
|
удалить
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endsection
|
|
@ -3,10 +3,13 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate" />
|
@php
|
||||||
<meta http-equiv="pragma" content="no-cache" />
|
// phpcs:disable
|
||||||
<meta http-equiv="expires" content="0" />
|
echo '<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate" />';
|
||||||
|
echo '<meta http-equiv="pragma" content="no-cache" />';
|
||||||
|
echo '<meta http-equiv="expires" content="0" />';
|
||||||
|
// phpcs:enable
|
||||||
|
@endphp
|
||||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||||
<meta name="csrf-param" content="_token"/>
|
<meta name="csrf-param" content="_token"/>
|
||||||
<title>Панель администратора</title>
|
<title>Панель администратора</title>
|
||||||
|
@ -49,6 +52,7 @@
|
||||||
<aside class="col-2">
|
<aside class="col-2">
|
||||||
<ul class="list-group ">
|
<ul class="list-group ">
|
||||||
<li class="list-group-item {{ request()->is('admin/news*') ? 'active' : '' }}"><a class="{{ request()->is('admin/news*') ? 'link-light' : '' }}" href="{{ route('news.index') }}">Новости</a></li>
|
<li class="list-group-item {{ request()->is('admin/news*') ? 'active' : '' }}"><a class="{{ request()->is('admin/news*') ? 'link-light' : '' }}" href="{{ route('news.index') }}">Новости</a></li>
|
||||||
|
<li class="list-group-item {{ request()->is('admin/feedback*') && !request()->is('admin/feedback_statuses*') ? 'active' : '' }}"><a class="{{ request()->is('admin/feedback*') && !request()->is('admin/feedback_statuses*') ? 'link-light' : '' }}" href="{{ route('feedback.index') }}">Обратная связь</a></li>
|
||||||
<li class="list-group-item {{ request()->is('admin/documents*') ? 'active' : '' }}"><a class="{{ request()->is('admin/documents*') ? 'link-light' : '' }}" href="{{ route('documents.index') }}">Документы</a></li>
|
<li class="list-group-item {{ request()->is('admin/documents*') ? 'active' : '' }}"><a class="{{ request()->is('admin/documents*') ? 'link-light' : '' }}" href="{{ route('documents.index') }}">Документы</a></li>
|
||||||
<li class="list-group-item {{ request()->is('admin/admissions*') ? 'active' : '' }}"><a class="{{ request()->is('admin/admissions*') ? 'link-light' : '' }}" href="{{ route('admissions.index') }}">Экран Приема</a></li>
|
<li class="list-group-item {{ request()->is('admin/admissions*') ? 'active' : '' }}"><a class="{{ request()->is('admin/admissions*') ? 'link-light' : '' }}" href="{{ route('admissions.index') }}">Экран Приема</a></li>
|
||||||
<li class="list-group-item {{ request()->is('admin/directions*') ? 'active' : '' }}"><a class="{{ request()->is('admin/directions*') ? 'link-light' : '' }}" href="{{ route('directions.index') }}">Направления</a></li>
|
<li class="list-group-item {{ request()->is('admin/directions*') ? 'active' : '' }}"><a class="{{ request()->is('admin/directions*') ? 'link-light' : '' }}" href="{{ route('directions.index') }}">Направления</a></li>
|
||||||
|
@ -70,6 +74,8 @@
|
||||||
<li class="list-group-item {{ request()->is('admin/subjects*') ? 'active' : '' }}"><a class="{{ request()->is('admin/subjects*') ? 'link-light' : '' }}" href="{{ route('subjects.index') }}">Предметы</a></li>
|
<li class="list-group-item {{ request()->is('admin/subjects*') ? 'active' : '' }}"><a class="{{ request()->is('admin/subjects*') ? 'link-light' : '' }}" href="{{ route('subjects.index') }}">Предметы</a></li>
|
||||||
<li class="list-group-item {{ request()->is('admin/subject_types*') ? 'active' : '' }}"><a class="{{ request()->is('admin/subject_types*') ? 'link-light' : '' }}" href="{{ route('subject_types.index') }}">Типы Предметов</a></li>
|
<li class="list-group-item {{ request()->is('admin/subject_types*') ? 'active' : '' }}"><a class="{{ request()->is('admin/subject_types*') ? 'link-light' : '' }}" href="{{ route('subject_types.index') }}">Типы Предметов</a></li>
|
||||||
<li class="list-group-item {{ request()->is('admin/direction_profiles*') ? 'active' : '' }}"><a class="{{ request()->is('admin/direction_profiles*') ? 'link-light' : '' }}" href="{{ route('direction_profiles.index') }}">Профили подготовки</a></li>
|
<li class="list-group-item {{ request()->is('admin/direction_profiles*') ? 'active' : '' }}"><a class="{{ request()->is('admin/direction_profiles*') ? 'link-light' : '' }}" href="{{ route('direction_profiles.index') }}">Профили подготовки</a></li>
|
||||||
|
<li class="list-group-item"></li>
|
||||||
|
<li class="list-group-item {{ request()->is('admin/feedback_statuses*') ? 'active' : '' }}"><a class="{{ request()->is('admin/feedback_statuses*') ? 'link-light' : '' }}" href="{{ route('feedback_statuses.index') }}">Статусы Обр. связи</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</aside>
|
</aside>
|
||||||
<main class="col-10">@yield('content')</main>
|
<main class="col-10">@yield('content')</main>
|
||||||
|
|
|
@ -13,6 +13,8 @@ use App\Http\Controllers\admin\Catalog\DirectionController;
|
||||||
use App\Http\Controllers\admin\Catalog\EducationalInstitutionController;
|
use App\Http\Controllers\admin\Catalog\EducationalInstitutionController;
|
||||||
use App\Http\Controllers\admin\Catalog\FacultyController;
|
use App\Http\Controllers\admin\Catalog\FacultyController;
|
||||||
use App\Http\Controllers\admin\DocumentController;
|
use App\Http\Controllers\admin\DocumentController;
|
||||||
|
use App\Http\Controllers\admin\FeedbackController;
|
||||||
|
use App\Http\Controllers\admin\FeedbackStatusController;
|
||||||
use App\Http\Controllers\admin\UserController;
|
use App\Http\Controllers\admin\UserController;
|
||||||
use App\Http\Controllers\NewsController;
|
use App\Http\Controllers\NewsController;
|
||||||
use Rap2hpoutre\LaravelLogViewer\LogViewerController;
|
use Rap2hpoutre\LaravelLogViewer\LogViewerController;
|
||||||
|
@ -68,6 +70,9 @@ Route::middleware(['auth', 'verified'])->prefix('admin')->group(function () {
|
||||||
Route::resource('/direction_profiles', DirectionProfileController::class)
|
Route::resource('/direction_profiles', DirectionProfileController::class)
|
||||||
->scoped(['direction_profile' => 'slug']);
|
->scoped(['direction_profile' => 'slug']);
|
||||||
|
|
||||||
|
Route::resource('/feedback', FeedbackController::class)->only(['index', 'edit', 'update']);
|
||||||
|
Route::resource('/feedback_statuses', FeedbackStatusController::class);
|
||||||
|
|
||||||
Route::resources([
|
Route::resources([
|
||||||
'/documents' => DocumentController::class,
|
'/documents' => DocumentController::class,
|
||||||
'/users' => UserController::class,
|
'/users' => UserController::class,
|
||||||
|
|
144
routes/pages.php
144
routes/pages.php
|
@ -1,5 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\admin\FeedbackController;
|
||||||
use App\Http\Controllers\admin\PageController;
|
use App\Http\Controllers\admin\PageController;
|
||||||
use App\Models\Faculty;
|
use App\Models\Faculty;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
@ -18,82 +19,81 @@ Route::get('/inostran', [PageController::class, 'inostran'])->name('inostran');
|
||||||
Route::get('/magistr', [PageController::class, 'magistr'])->name('magistr');
|
Route::get('/magistr', [PageController::class, 'magistr'])->name('magistr');
|
||||||
|
|
||||||
|
|
||||||
|
Route::post('/feedback', [FeedbackController::class, 'store'])->name('feedback.store');
|
||||||
|
|
||||||
|
|
||||||
|
//Route::get('/course', function () {
|
||||||
|
// return view('menu.course');
|
||||||
Route::get('/course', function () {
|
//})->name('course');
|
||||||
return view('menu.course');
|
//
|
||||||
})->name('course');
|
//Route::get('/applicant', function () {
|
||||||
|
// return view('menu.abitur');
|
||||||
Route::get('/applicant', function () {
|
//})->name('abitur');
|
||||||
return view('menu.abitur');
|
//
|
||||||
})->name('abitur');
|
//Route::get('/for-foreign-applicants', function () {
|
||||||
|
// return view('menu.inostrannym-abiturientam');
|
||||||
Route::get('/for-foreign-applicants', function () {
|
//})->name('inostrannym-abiturientam');
|
||||||
return view('menu.inostrannym-abiturientam');
|
//
|
||||||
})->name('inostrannym-abiturientam');
|
//Route::get('/paid_edu', function () {
|
||||||
|
// return view('menu.paid_edu');
|
||||||
Route::get('/paid_edu', function () {
|
//})->name('paid_edu');
|
||||||
return view('menu.paid_edu');
|
//
|
||||||
})->name('paid_edu');
|
//Route::get('/olympiads-for-schoolchildren', function () {
|
||||||
|
// return view('menu.olimpiady-dlya-shkolnikov');
|
||||||
Route::get('/olympiads-for-schoolchildren', function () {
|
//})->name('olimpiady-dlya-shkolnikov');
|
||||||
return view('menu.olimpiady-dlya-shkolnikov');
|
//
|
||||||
})->name('olimpiady-dlya-shkolnikov');
|
//Route::get('/training courses', function () {
|
||||||
|
// return view('menu.podgotovitelnye-kursy');
|
||||||
Route::get('/training courses', function () {
|
//})->name('podgotovitelnye-kursy');
|
||||||
return view('menu.podgotovitelnye-kursy');
|
|
||||||
})->name('podgotovitelnye-kursy');
|
|
||||||
|
|
||||||
|
|
||||||
Route::get('/reception-screens', [PageController::class, 'index'])->name('reception-screens');
|
Route::get('/reception-screens', [PageController::class, 'index'])->name('reception-screens');
|
||||||
|
|
||||||
|
|
||||||
Route::get('/web-consultations', function () {
|
//Route::get('/web-consultations', function () {
|
||||||
return view('menu.abitur.web-consultations');
|
// return view('menu.abitur.web-consultations');
|
||||||
})->name('web-consultations');
|
//})->name('web-consultations');
|
||||||
|
//
|
||||||
Route::get('/specialty-magistracy', function () {
|
//Route::get('/specialty-magistracy', function () {
|
||||||
return view('menu.abitur.spetsialitet-magistratura');
|
// return view('menu.abitur.spetsialitet-magistratura');
|
||||||
})->name('spetsialitet-magistratura');
|
//})->name('spetsialitet-magistratura');
|
||||||
|
//
|
||||||
Route::get('/college', function () {
|
//Route::get('/college', function () {
|
||||||
return view('menu.abitur.kolledzh');
|
// return view('menu.abitur.kolledzh');
|
||||||
})->name('kolledzh');
|
//})->name('kolledzh');
|
||||||
|
//
|
||||||
Route::get('/paid-educational-services', function () {
|
//Route::get('/paid-educational-services', function () {
|
||||||
return view('menu.abitur.platnye-obrazovatelnye-uslugi');
|
// return view('menu.abitur.platnye-obrazovatelnye-uslugi');
|
||||||
})->name('platnye-obrazovatelnye-uslugi');
|
//})->name('platnye-obrazovatelnye-uslugi');
|
||||||
|
//
|
||||||
Route::get('/residency', function () {
|
//Route::get('/residency', function () {
|
||||||
return view('menu.abitur.ordinatura');
|
// return view('menu.abitur.ordinatura');
|
||||||
})->name('ordinatura');
|
//})->name('ordinatura');
|
||||||
|
//
|
||||||
Route::get('/traineeship', function () {
|
//Route::get('/traineeship', function () {
|
||||||
return view('menu.abitur.aspirantura');
|
// return view('menu.abitur.aspirantura');
|
||||||
})->name('aspirantura');
|
//})->name('aspirantura');
|
||||||
|
//
|
||||||
Route::get('/video-materials-for-applicants', function () {
|
//Route::get('/video-materials-for-applicants', function () {
|
||||||
return view('menu.abitur.videomaterialy-dlya-postupayushchikh');
|
// return view('menu.abitur.videomaterialy-dlya-postupayushchikh');
|
||||||
})->name('videomaterialy-dlya-postupayushchikh');
|
//})->name('videomaterialy-dlya-postupayushchikh');
|
||||||
|
//
|
||||||
Route::get('/international-activity', function () {
|
//Route::get('/international-activity', function () {
|
||||||
return view('menu.inostrannym-abiturientam.mezhdunarodnaya-deyatelnost');
|
// return view('menu.inostrannym-abiturientam.mezhdunarodnaya-deyatelnost');
|
||||||
})->name('mezhdunarodnaya-deyatelnost');
|
//})->name('mezhdunarodnaya-deyatelnost');
|
||||||
|
//
|
||||||
Route::get('/general-information', function () {
|
//Route::get('/general-information', function () {
|
||||||
return view('menu.inostrannym-abiturientam.obshchie-svedeniya');
|
// return view('menu.inostrannym-abiturientam.obshchie-svedeniya');
|
||||||
})->name('obshchie-svedeniya');
|
//})->name('obshchie-svedeniya');
|
||||||
|
//
|
||||||
Route::get('/departments-list', function () {
|
//Route::get('/departments-list', function () {
|
||||||
return view('menu.inostrannym-abiturientam.kafedry');
|
// return view('menu.inostrannym-abiturientam.kafedry');
|
||||||
})->name('kafedry');
|
//})->name('kafedry');
|
||||||
|
//
|
||||||
Route::get('/international-education-center', function () {
|
//Route::get('/international-education-center', function () {
|
||||||
return view('menu.inostrannym-abiturientam.tsentr-mezhdunarodnogo-obrazovaniya');
|
// return view('menu.inostrannym-abiturientam.tsentr-mezhdunarodnogo-obrazovaniya');
|
||||||
})->name('tsentr-mezhdunarodnogo-obrazovaniya');
|
//})->name('tsentr-mezhdunarodnogo-obrazovaniya');
|
||||||
|
//
|
||||||
Route::get('/academic-mobility-and-international-cooperation', function () {
|
//Route::get('/academic-mobility-and-international-cooperation', function () {
|
||||||
return view('menu.inostrannym-abiturientam.akademicheskaya-mobilnost-i-mezhdunarodnoe-sotrudnichestvo');
|
// return view('menu.inostrannym-abiturientam.akademicheskaya-mobilnost-i-mezhdunarodnoe-sotrudnichestvo');
|
||||||
})->name('akademicheskaya-mobilnost-i-mezhdunarodnoe-sotrudnichestvo');
|
//})->name('akademicheskaya-mobilnost-i-mezhdunarodnoe-sotrudnichestvo');
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\admin;
|
||||||
|
|
||||||
|
use App\Models\FeedbackStatus;
|
||||||
|
use App\Models\News;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class FeedbackStatusTest extends TestCase
|
||||||
|
{
|
||||||
|
private User $user;
|
||||||
|
private FeedbackStatus $status;
|
||||||
|
private array $data;
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->status = FeedbackStatus::factory()->create();
|
||||||
|
$this->data = FeedbackStatus::factory()->make()->only([
|
||||||
|
'name',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->user = User::factory()->create([
|
||||||
|
'name' => 'admin',
|
||||||
|
'email' => 'test@example.com',
|
||||||
|
'password' => 123456
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIndexFeedbackStatusPage(): void
|
||||||
|
{
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->withSession(['banned' => false])
|
||||||
|
->get(route('feedback_statuses.index'));
|
||||||
|
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateFeedbackStatusPage(): void
|
||||||
|
{
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->withSession(['banned' => false])
|
||||||
|
->get(route('feedback_statuses.create'));
|
||||||
|
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStoreFeedbackStatus(): void
|
||||||
|
{
|
||||||
|
$file = UploadedFile::fake()->create('fake.jpg', 100);
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->withSession(['banned' => false])
|
||||||
|
->post(route('feedback_statuses.store'), $this->data);
|
||||||
|
|
||||||
|
$response->assertRedirect(route('feedback_statuses.index'));
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('feedback_statuses', $this->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEditFeedbackStatusPage(): void
|
||||||
|
{
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->withSession(['banned' => false])
|
||||||
|
->get(route('feedback_statuses.edit', $this->status));
|
||||||
|
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdateFeedbackStatus(): void
|
||||||
|
{
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->withSession(['banned' => false])
|
||||||
|
->patch(route('feedback_statuses.update', $this->status), $this->data);
|
||||||
|
|
||||||
|
$response->assertRedirect(route('feedback_statuses.index'));
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('feedback_statuses', $this->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDestroyFeedbackStatus(): void
|
||||||
|
{
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->withSession(['banned' => false])
|
||||||
|
->delete(route('feedback_statuses.destroy', $this->status));
|
||||||
|
|
||||||
|
$response->assertRedirect(route('feedback_statuses.index'));
|
||||||
|
|
||||||
|
$this->assertDatabaseMissing('feedback_statuses', $this->status->toArray());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\admin;
|
||||||
|
|
||||||
|
use App\Models\Feedback;
|
||||||
|
use App\Models\FeedbackStatus;
|
||||||
|
use App\Models\News;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class FeedbackTest extends TestCase
|
||||||
|
{
|
||||||
|
private User $user;
|
||||||
|
private Feedback $feedback;
|
||||||
|
private array $data;
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->feedbackStatus = FeedbackStatus::factory()->create();
|
||||||
|
$this->feedback = Feedback::factory()->create();
|
||||||
|
$this->data = Feedback::factory()->make()->only([
|
||||||
|
'contact',
|
||||||
|
'text',
|
||||||
|
'status_id',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->user = User::factory()->create([
|
||||||
|
'name' => 'admin',
|
||||||
|
'email' => 'test@example.com',
|
||||||
|
'password' => 123456
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIndexFeedbacksPage(): void
|
||||||
|
{
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->withSession(['banned' => false])
|
||||||
|
->get(route('feedback.index'));
|
||||||
|
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStoreFeedback(): void
|
||||||
|
{
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->withSession(['banned' => false])
|
||||||
|
->post(route('feedback.store'), $this->data);
|
||||||
|
|
||||||
|
$response->assertJson(["result" => "success"]);
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('feedback', $this->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEditFeedbackPage(): void
|
||||||
|
{
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->withSession(['banned' => false])
|
||||||
|
->get(route('feedback.edit', $this->feedback));
|
||||||
|
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdateFeedback(): void
|
||||||
|
{
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->withSession(['banned' => false])
|
||||||
|
->patch(route('feedback.update', $this->feedback), $this->data);
|
||||||
|
|
||||||
|
$response->assertRedirect(route('feedback.index'));
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('feedback', $this->data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Tests\Feature\admin\catalog;
|
namespace Tests\Feature\admin;
|
||||||
|
|
||||||
use App\Models\Department;
|
|
||||||
use App\Models\EducationalInstitution;
|
|
||||||
use App\Models\Faculty;
|
|
||||||
use App\Models\News;
|
use App\Models\News;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
Loading…
Reference in New Issue