Compare commits
3 Commits
38e31a9e3d
...
30a3ff49c6
Author | SHA1 | Date | |
---|---|---|---|
|
30a3ff49c6 | ||
|
ab5990c060 | ||
|
84ab4777c2 |
|
@ -4,58 +4,116 @@ namespace App\Http\Controllers\API;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use App\Models\User;
|
||||||
|
|
||||||
class AuthController extends Controller
|
class AuthController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Create user
|
||||||
|
*
|
||||||
|
* @param [string] name
|
||||||
|
* @param [string] email
|
||||||
|
* @param [string] password
|
||||||
|
* @param [string] password_confirmation
|
||||||
|
* @return [string] message
|
||||||
|
*/
|
||||||
public function register(Request $request)
|
public function register(Request $request)
|
||||||
{
|
{
|
||||||
$validator = Validator::make($request->all(), [
|
$request->validate([
|
||||||
'name' => 'required',
|
'name' => 'required|string',
|
||||||
'email' => 'required|email|unique:users',
|
'email'=>'required|string|unique:users',
|
||||||
'password' => 'required',
|
'password'=>'required|string',
|
||||||
|
'c_password' => 'required|same:password'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
$user = new User([
|
||||||
return response()->json($validator->errors(), 422);
|
'name' => $request->name,
|
||||||
}
|
|
||||||
|
|
||||||
$user = User::create([
|
|
||||||
'name' => $request->name,
|
|
||||||
'email' => $request->email,
|
'email' => $request->email,
|
||||||
'password' => bcrypt($request->password),
|
'password' => bcrypt($request->password),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$token = $user->createToken('auth_token')->plainTextToken;
|
if($user->save()){
|
||||||
|
$tokenResult = $user->createToken('Personal Access Token');
|
||||||
|
$token = $tokenResult->plainTextToken;
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'user' => $user,
|
'message' => 'Successfully created user!',
|
||||||
'token' => $token,
|
'user' => $user,
|
||||||
]);
|
'accessToken'=> $token,
|
||||||
|
],201);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return response()->json(['error'=>'Provide proper details']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login user and create token
|
||||||
|
*
|
||||||
|
* @param [string] email
|
||||||
|
* @param [string] password
|
||||||
|
* @param [boolean] remember_me
|
||||||
|
*/
|
||||||
public function login(Request $request)
|
public function login(Request $request)
|
||||||
{
|
{
|
||||||
if (!Auth::attempt($request->only('email', 'password'))) {
|
$request->validate([
|
||||||
return response()->json(['message' => 'Invalid login details'], 401);
|
'email' => 'required|string|email',
|
||||||
|
'password' => 'required|string',
|
||||||
|
'remember_me' => 'boolean'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$credentials = request(['email','password']);
|
||||||
|
if(!Auth::attempt($credentials))
|
||||||
|
{
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Unauthorized'
|
||||||
|
],401);
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = User::where('email', $request['email'])->firstOrFail();
|
$user = $request->user();
|
||||||
|
$tokenResult = $user->createToken('Personal Access Token');
|
||||||
$token = $user->createToken('auth_token')->plainTextToken;
|
$token = $tokenResult->plainTextToken;
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
'accessToken' =>$token,
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
'token' => $token,
|
'token_type' => 'Bearer',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the authenticated User
|
||||||
|
*
|
||||||
|
* @return [json] user object
|
||||||
|
*/
|
||||||
|
public function user(Request $request)
|
||||||
|
{
|
||||||
|
return response()->json($request->user());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the authenticated User
|
||||||
|
*
|
||||||
|
* @return [json] user object
|
||||||
|
*/
|
||||||
|
public function username(Request $request)
|
||||||
|
{
|
||||||
|
return response()->json($request->user()['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logout user (Revoke the token)
|
||||||
|
*
|
||||||
|
* @return [string] message
|
||||||
|
*/
|
||||||
public function logout(Request $request)
|
public function logout(Request $request)
|
||||||
{
|
{
|
||||||
$request->user()->currentAccessToken()->delete();
|
$request->user()->tokens()->delete();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Successfully logged out'
|
||||||
|
]);
|
||||||
|
|
||||||
return response()->json(['message' => 'Logged out']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Computer;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ComputerController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return Computer::select()->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getById(Request $request){
|
||||||
|
return Computer::find($request->get('id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByUserId(Request $request){
|
||||||
|
return Computer::select()->where('user_id', '=', $request->get('user_id'))->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'user_id' => 'required|exists:users,id',
|
||||||
|
'name' => 'required|string|max:256',
|
||||||
|
'cpu' => 'nullable|string|max:256',
|
||||||
|
'motherboard' => 'nullable|string|max:256',
|
||||||
|
'gpu' => 'nullable|string|max:256',
|
||||||
|
'additional_info' => 'nullable|string|max:256',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$computer = Computer::create($request->all());
|
||||||
|
return response()->json($computer, 201);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'id' => 'required|exists:computers,id',
|
||||||
|
'name' => 'required|string|max:256',
|
||||||
|
'cpu' => 'nullable|string|max:256',
|
||||||
|
'motherboard' => 'nullable|string|max:256',
|
||||||
|
'gpu' => 'nullable|string|max:256',
|
||||||
|
'additional_info' => 'nullable|string|max:256',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$computer = Computer::find($request->get('id'));
|
||||||
|
$computer->name = $request->get('name');
|
||||||
|
$computer->cpu = $request->get('cpu');
|
||||||
|
$computer->motherboard = $request->get('motherboard');
|
||||||
|
$computer->gpu = $request->get('gpu');
|
||||||
|
$computer->additional_info = $request->get('additional_info');
|
||||||
|
$computer->save();
|
||||||
|
return response()->json($computer);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'id' => 'required|exists:wishes,id',
|
||||||
|
]);
|
||||||
|
$destroyed = Computer::destroy($request->get('id'));
|
||||||
|
return response()->json($destroyed, 204);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Job;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class JobController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return Job::select()->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByComputerId(Request $request){
|
||||||
|
return Job::select()->where('computer_id', '=', $request->get('computer_id'))->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'computer_id' => 'required|exists:computers,id',
|
||||||
|
'description' => 'required|string|max:256',
|
||||||
|
'status' => 'nullable|boolean'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$job = Job::create($request->all());
|
||||||
|
return response()->json($job, 201);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'id' => 'required|exists:jobs,id',
|
||||||
|
'computer_id' => 'required|exists:computers,id',
|
||||||
|
'description' => 'required|string|max:256',
|
||||||
|
'status' => 'nullable|boolean'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$job = Job::find($request->get('id'));
|
||||||
|
$job->computer_id = $request->get('computer_id');
|
||||||
|
$job->description = $request->get('description');
|
||||||
|
$job->status = $request->get('status');
|
||||||
|
$job->save();
|
||||||
|
return response()->json($job);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'id' => 'required|exists:jobs,id',
|
||||||
|
]);
|
||||||
|
$destroyed = Job::destroy($request->get('id'));
|
||||||
|
return response()->json($destroyed, 204);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Computer extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Job extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?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('computers', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('user_id');
|
||||||
|
$table->foreign('user_id')->references('id')->on('users');
|
||||||
|
$table->string('name', length: 256);
|
||||||
|
$table->string('cpu', length: 256)->nullable();
|
||||||
|
$table->string('motherboard', length: 256)->nullable();
|
||||||
|
$table->string('gpu', length: 256)->nullable();
|
||||||
|
$table->string('additional_info', length: 256)->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('computers');
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?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('jobs', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('computer_id');
|
||||||
|
$table->foreign('computer_id')->references('id')->on('computers');
|
||||||
|
$table->string('description', length: 256);
|
||||||
|
$table->boolean('status')->default(false);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('jobs');
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<path d="M6,2C4.89,2 4,2.89 4,4V12C4,13.11 4.89,14 6,14H18C19.11,14 20,13.11 20,12V4C20,2.89 19.11,2 18,2H6M6,4H18V12H6V4M4,15C2.89,15 2,15.89 2,17V20C2,21.11 2.89,22 4,22H20C21.11,22 22,21.11 22,20V17C22,15.89 21.11,15 20,15H4M8,17H20V20H8V17M9,17.75V19.25H13V17.75H9M15,17.75V19.25H19V17.75H15Z" style="fill: rgb(42, 139, 42);"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 440 B |
|
@ -27,13 +27,18 @@
|
||||||
</div>
|
</div>
|
||||||
<v-sheet
|
<v-sheet
|
||||||
v-if="isWide || menuOpen"
|
v-if="isWide || menuOpen"
|
||||||
class="d-flex justify-end rounded-lg main-bg h-auto mr-10 ml-10"
|
class="d-flex justify-space-between rounded-lg main-bg h-auto mr-10 ml-10 align-center"
|
||||||
:class="menuOpen ? 'mt-2 mb-2 pa-2' : 'mt-10 mb-3 pa-5'"
|
:class="menuOpen ? 'mt-2 mb-2 pa-2 flex-column' : 'mt-10 mb-3 pa-5'"
|
||||||
>
|
>
|
||||||
<p class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><RouterLink to="/" class="nav-link text-decoration-none">Главная</RouterLink></p>
|
<div class="d-flex justify-center rounded-lg main-bg h-auto mr-10 ml-10">
|
||||||
<p v-if="user == null" class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><RouterLink to="/login" class="nav-link text-decoration-none">Войти</RouterLink></p>
|
<v-label class="text-h6 h-auto w-auto pa-2">Welcome {{ authenticated ? userStore.user['name'] : 'guest' }}!</v-label><br>
|
||||||
<p v-if="user == null" class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><RouterLink to="/register" class="nav-link text-decoration-none">Регистрация</RouterLink></p>
|
</div>
|
||||||
<p v-else class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><a href="#" class="nav-link text-decoration-none" @click="logout">Выйти</a></p>
|
<div class="d-flex" :class="menuOpen ? 'justify-center' : 'justify-end'">
|
||||||
|
<p class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><RouterLink to="/" class="nav-link text-decoration-none">Главная</RouterLink></p>
|
||||||
|
<p v-if="!authenticated" class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><RouterLink to="/login" class="nav-link text-decoration-none">Войти</RouterLink></p>
|
||||||
|
<p v-if="!authenticated" class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><RouterLink to="/register" class="nav-link text-decoration-none">Регистрация</RouterLink></p>
|
||||||
|
<p v-if="authenticated" class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><a href="#" class="nav-link text-decoration-none" @click="logout">Выйти</a></p>
|
||||||
|
</div>
|
||||||
</v-sheet>
|
</v-sheet>
|
||||||
<v-sheet class="rounded-lg main-bg h-100 mt-3 mr-10 ml-10 mb-10 pa-5">
|
<v-sheet class="rounded-lg main-bg h-100 mt-3 mr-10 ml-10 mb-10 pa-5">
|
||||||
<RouterView v-slot="{ Component }">
|
<RouterView v-slot="{ Component }">
|
||||||
|
@ -48,28 +53,23 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {th} from "vuetify/locale";
|
import {useUserStore} from "./store/auth.js";
|
||||||
import {useAuthStore} from "./store/auth.js";
|
import {watch} from "vue";
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
data: () => ({
|
data: () => ({
|
||||||
|
userStore: useUserStore(),
|
||||||
windowHeight: document.documentElement.clientHeight,
|
windowHeight: document.documentElement.clientHeight,
|
||||||
windowWidth: document.documentElement.clientWidth,
|
windowWidth: document.documentElement.clientWidth,
|
||||||
isWide: window.innerWidth >= 460,
|
isWide: window.innerWidth >= 460,
|
||||||
menuOpen: false
|
menuOpen: false,
|
||||||
|
authenticated: false
|
||||||
}),
|
}),
|
||||||
computed: {
|
|
||||||
user() {
|
|
||||||
const authStore = useAuthStore();
|
|
||||||
return authStore.user;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
logout() {
|
logout() {
|
||||||
const authStore = useAuthStore();
|
this.userStore.logout();
|
||||||
authStore.logout();
|
|
||||||
this.username = 'guest';
|
|
||||||
this.$router.push('/login');
|
this.$router.push('/login');
|
||||||
},
|
},
|
||||||
resizeEventHandler(e) {
|
resizeEventHandler(e) {
|
||||||
|
@ -90,6 +90,10 @@ export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
this.resizeEventHandler();
|
this.resizeEventHandler();
|
||||||
window.addEventListener("resize", this.resizeEventHandler, { passive: true });
|
window.addEventListener("resize", this.resizeEventHandler, { passive: true });
|
||||||
|
this.userStore.checkUser();
|
||||||
|
watch(this.userStore, (newStore)=>{
|
||||||
|
this.authenticated = newStore.user !== null && newStore.user !== undefined;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -7,7 +7,8 @@ import * as components from 'vuetify/components'
|
||||||
import * as directives from 'vuetify/directives'
|
import * as directives from 'vuetify/directives'
|
||||||
import '@mdi/font/css/materialdesignicons.css'
|
import '@mdi/font/css/materialdesignicons.css'
|
||||||
import Login from "./views/Login.vue";
|
import Login from "./views/Login.vue";
|
||||||
import About from "./views/About.vue";
|
import ComputersList from "./views/ComputersList.vue";
|
||||||
|
import JobsList from "./views/JobsList.vue";
|
||||||
import Register from "./views/Register.vue";
|
import Register from "./views/Register.vue";
|
||||||
import {createMemoryHistory, createRouter} from "vue-router";
|
import {createMemoryHistory, createRouter} from "vue-router";
|
||||||
import { createPinia } from 'pinia';
|
import { createPinia } from 'pinia';
|
||||||
|
@ -15,9 +16,10 @@ import { createPinia } from 'pinia';
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{path: '/', component: About, props: true},
|
{path: '/', component: ComputersList, props: true},
|
||||||
{path: '/login', component: Login, props: true},
|
{path: '/login', component: Login, props: true},
|
||||||
{path: '/register', component: Register, props: true}
|
{path: '/register', component: Register, props: true},
|
||||||
|
{path: '/jobs', component: JobsList, props: true},
|
||||||
]
|
]
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|
|
@ -4,6 +4,14 @@
|
||||||
text-decoration-color: #e0e0e0!important;
|
text-decoration-color: #e0e0e0!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cursor-pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-decoration-none {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
.bg-gradient {
|
.bg-gradient {
|
||||||
background: linear-gradient(-45deg, #f103b0, #f0a068, #4fdbfeff)!important;
|
background: linear-gradient(-45deg, #f103b0, #f0a068, #4fdbfeff)!important;
|
||||||
background-size: 200% 200%!important;
|
background-size: 200% 200%!important;
|
||||||
|
@ -204,7 +212,7 @@
|
||||||
stroke-dashoffset: -64px;
|
stroke-dashoffset: -64px;
|
||||||
}
|
}
|
||||||
.ham8.active .middle {
|
.ham8.active .middle {
|
||||||
//stroke-dashoffset: -20px;
|
/*stroke-dashoffset: -20px;*/
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
.ham8.active .bottom {
|
.ham8.active .bottom {
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
export const rules = {
|
||||||
|
email: value => {
|
||||||
|
const pattern = /^[A-Za-z0-9\._]+@{1}[A-Za-z0-9]+\.[a-z]+$/
|
||||||
|
return pattern.test(value) || 'Неверный email'
|
||||||
|
},
|
||||||
|
notNull: value => {
|
||||||
|
return (value !== null && value !== undefined && value !== '') || 'Поле не может быть пустым';
|
||||||
|
},
|
||||||
|
id: value => {
|
||||||
|
return (value !== null && value !== undefined && typeof value == 'number') || 'Неверный id';
|
||||||
|
},
|
||||||
|
price: value => {
|
||||||
|
return (typeof value == 'number' || typeof value == 'undefined' || value === null) || 'Стоимость должна быть числом';
|
||||||
|
},
|
||||||
|
isNumber: value => {
|
||||||
|
return /^\d+[\.,\,]?\d*$/.test(value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,31 +1,103 @@
|
||||||
import { defineStore } from 'pinia';
|
import {defineStore} from 'pinia'
|
||||||
import axios from 'axios';
|
import axios from "axios";
|
||||||
|
|
||||||
export const useAuthStore = defineStore('auth', {
|
export const useUserStore = defineStore('user', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
user: null,
|
user: null,
|
||||||
token: localStorage.getItem('token') || null,
|
token: localStorage.getItem('auth_token') || null,
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
async login(credentials) {
|
setUser(user) {
|
||||||
const response = await axios.post('/api/login', credentials);
|
this.user = user;
|
||||||
this.user = response.data.user;
|
|
||||||
this.token = response.data.token;
|
|
||||||
localStorage.setItem('token', response.data.token);
|
|
||||||
},
|
},
|
||||||
async register(credentials) {
|
setToken(token) {
|
||||||
const response = await axios.post('/api/register', credentials);
|
this.token = token;
|
||||||
this.user = response.data.user;
|
localStorage.setItem('auth_token', token);
|
||||||
this.token = response.data.token;
|
},
|
||||||
localStorage.setItem('token', response.data.token);
|
async checkUser() {
|
||||||
|
await axios.get(
|
||||||
|
'/api/auth/user',
|
||||||
|
{
|
||||||
|
headers:
|
||||||
|
{
|
||||||
|
Authorization: `Bearer ${this.token}`,
|
||||||
|
token: this.token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then((res) => {
|
||||||
|
this.setUser(res.data);
|
||||||
|
return true;
|
||||||
|
}).catch((error) => {
|
||||||
|
this.nullifyUser();
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async login(email, password, rememberMe) {
|
||||||
|
await axios.post(
|
||||||
|
'/api/auth/login',
|
||||||
|
{
|
||||||
|
'email': email,
|
||||||
|
'password': password,
|
||||||
|
'remember_me': rememberMe
|
||||||
|
}).then((res) => {
|
||||||
|
this.setUser(res.data.user);
|
||||||
|
this.setToken(res.data.accessToken);
|
||||||
|
return true;
|
||||||
|
}).catch((error) => {
|
||||||
|
if (!error.response) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return error.response.data.message;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async registration(login, email, password, repeatPassword) {
|
||||||
|
await axios.post(
|
||||||
|
'/api/auth/register',
|
||||||
|
{
|
||||||
|
'name': login,
|
||||||
|
'email': email,
|
||||||
|
'password': password,
|
||||||
|
'c_password': repeatPassword
|
||||||
|
}).then((res) => {
|
||||||
|
this.setUser(res.data.user);
|
||||||
|
this.setToken(res.data.accessToken);
|
||||||
|
return true;
|
||||||
|
}).catch((error) => {
|
||||||
|
if (!error.response) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return error.response.data.message;
|
||||||
|
})
|
||||||
},
|
},
|
||||||
logout() {
|
logout() {
|
||||||
this.user = null;
|
axios.get('/api/auth/logout',
|
||||||
this.token = null;
|
{
|
||||||
localStorage.removeItem('token');
|
headers:
|
||||||
|
{
|
||||||
|
Authorization: `Bearer ${this.token}`,
|
||||||
|
token: this.token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.nullifyUser();
|
||||||
},
|
},
|
||||||
|
nullifyUser() {
|
||||||
|
this.setUser(null);
|
||||||
|
this.setToken(null);
|
||||||
|
},
|
||||||
|
async getUsername(id){
|
||||||
|
let result = null;
|
||||||
|
await axios.get('/api/wish/username',
|
||||||
|
{
|
||||||
|
params:
|
||||||
|
{
|
||||||
|
user_id: id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then((res) => {
|
||||||
|
result = res;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
})
|
||||||
isAuthenticated: (state) => !!state.token,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import {defineStore} from 'pinia'
|
||||||
|
import axios from "axios";
|
||||||
|
import {useUserStore} from "./auth.js";
|
||||||
|
|
||||||
|
export const useComputersStore = defineStore('computers', {
|
||||||
|
state: () => ({
|
||||||
|
computers: [],
|
||||||
|
token: null,
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
setToken(token) {
|
||||||
|
this.token = token;
|
||||||
|
localStorage.setItem('auth_token', token);
|
||||||
|
},
|
||||||
|
checkToken(){
|
||||||
|
this.token = this.useUserStore().token;
|
||||||
|
},
|
||||||
|
async getComputerList(user_id){
|
||||||
|
if (this.token === null){
|
||||||
|
this.checkToken();
|
||||||
|
}
|
||||||
|
await axios.get(
|
||||||
|
'/api/data/computers/byUser',
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${this.token}`,
|
||||||
|
token: this.token
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
user_id: user_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then((response)=>{
|
||||||
|
this.computers = response.data;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
|
@ -1,51 +0,0 @@
|
||||||
<script>
|
|
||||||
import { useAuthStore } from '../store/auth.js';
|
|
||||||
export default {
|
|
||||||
name: "About",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
username: 'guest'
|
|
||||||
};
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
isWide: Boolean
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
user() {
|
|
||||||
const authStore = useAuthStore();
|
|
||||||
return authStore.user;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
logout() {
|
|
||||||
const authStore = useAuthStore();
|
|
||||||
authStore.logout();
|
|
||||||
this.username = 'guest';
|
|
||||||
this.$router.push('/login');
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div v-if="user == null" class="d-flex justify-center align-center h-100 flex-column w-100">
|
|
||||||
<v-label class="text-h3 d-flex justify-center align-center" :class="isWide ? 'w-100' : 'w-10'">Welcome guest!</v-label><br>
|
|
||||||
<div class="d-flex justify-center align-center ma-5 w-100">
|
|
||||||
<router-link to="/register" class="ma-3 text-decoration-none link-no-color flex-grow-0 min-width-btn" :class="isWide ? 'w-10' : 'w-100'">
|
|
||||||
<v-btn color="#F0A068FF" class="pa-3" :class="isWide ? 'w-100' : 'w-100 text-body-1'">Регистрация</v-btn>
|
|
||||||
</router-link>
|
|
||||||
<router-link to="/login" class="ma-3 text-decoration-none link-no-color flex-grow-0 min-width-btn" :class="isWide ? 'w-10' : 'w-100'">
|
|
||||||
<v-btn color="#F0A068FF" class="pa-3" :class="isWide ? 'w-100' : 'w-100 text-body-1'">Вход</v-btn>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else class="d-flex justify-center align-center h-100 flex-column w-100">
|
|
||||||
<v-label class="text-h3 d-flex justify-center align-center" :class="isWide ? 'w-100' : 'w-10'">Welcome {{ user.name }}!</v-label>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.w-10 {
|
|
||||||
width: 10%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
<script>
|
||||||
|
import { watch } from 'vue';
|
||||||
|
import { useUserStore } from '../store/auth.js';
|
||||||
|
import {useComputersStore} from "../store/computers.js";
|
||||||
|
import {rules} from "../js/rules.js";
|
||||||
|
export default {
|
||||||
|
name: "About",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
userStore: useUserStore(),
|
||||||
|
computersStore: useComputersStore(),
|
||||||
|
computerList: [],
|
||||||
|
createDialogShow: false,
|
||||||
|
editDialogShow: false,
|
||||||
|
fetching: false,
|
||||||
|
authenticated: false,
|
||||||
|
computerName: null,
|
||||||
|
computerCpu: null,
|
||||||
|
computerMotherboard: null,
|
||||||
|
computerGpu: null,
|
||||||
|
computerAdditional: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showCreateDialog(){
|
||||||
|
this.createDialogShow = true;
|
||||||
|
},
|
||||||
|
showEditDialog(){
|
||||||
|
this.editDialogShow = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.userStore.checkUser();
|
||||||
|
watch(this.userStore, (newStore)=>{
|
||||||
|
this.fetching = true;
|
||||||
|
this.authenticated = newStore.user !== null && newStore.user !== undefined;
|
||||||
|
this.computersStore.setToken(this.userStore.token);
|
||||||
|
this.computersStore.getComputerList(this.userStore.user['id']).then(()=>{
|
||||||
|
this.computerList = this.computersStore.computers;
|
||||||
|
this.fetching = false;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="d-flex flex-column justify-center w-100">
|
||||||
|
<v-skeleton-loader v-if="fetching" color="grey-darken-3" class="w-100" type="card"/>
|
||||||
|
<div v-if="!fetching" class="w-100 h-100">
|
||||||
|
<div class="d-flex align-center justify-space-between w-100 h-100" v-for="computer in computerList">
|
||||||
|
<router-link :to="`/jobs?id=${computer['id']}`" class="text-decoration-none w-100 mr-2" >
|
||||||
|
<v-card class="card-bg text-decoration-none cursor-pointer w-100">
|
||||||
|
<v-card-title>{{ computer['name'] }}</v-card-title>
|
||||||
|
<v-card-text class="d-flex flex-column cursor-pointer">
|
||||||
|
<v-label class="cursor-pointer">CPU: {{ computer['cpu'] }}</v-label>
|
||||||
|
<v-label class="cursor-pointer">Motherboard: {{ computer['motherboard'] }}</v-label>
|
||||||
|
<v-label class="cursor-pointer">GPU: {{ computer['gpu'] }}</v-label>
|
||||||
|
<v-label class="cursor-pointer">Дополнительная информация: {{ computer['additional_info'] }}</v-label>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</router-link>
|
||||||
|
<div @click="showEditDialog" class="card-bg align-self-stretch pa-2 d-flex justify-center align-center rounded-sm">
|
||||||
|
<v-icon icon="mdi-pencil"></v-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-100 pa-5" v-if="!fetching">
|
||||||
|
<v-btn class="w-100" color="#F0A068FF" @click="showCreateDialog" rounded="xs">
|
||||||
|
<v-icon icon="mdi-plus-thick"></v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<v-dialog :model-value="createDialogShow">
|
||||||
|
<v-card class="main-bg">
|
||||||
|
<v-card-title>Создание нового компьютера</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<v-text-field label="Название" :model-value="computerName" placeholder="Мой компьютер"></v-text-field>
|
||||||
|
<v-text-field label="CPU" :model-value="computerCpu" placeholder="Intel Core i5-12400F"></v-text-field>
|
||||||
|
<v-text-field label="Материнская плата" :model-value="computerMotherboard" placeholder="Asus ROG B650"></v-text-field>
|
||||||
|
<v-text-field label="Gpu" :model-value="computerGpu" placeholder="Nvidia RTX 3060ti"></v-text-field>
|
||||||
|
<v-textarea label="Дополнительная информация" :model-value="computerAdditional"></v-textarea>
|
||||||
|
<v-btn>Создать</v-btn>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.card-bg {
|
||||||
|
background-color: #272727 !important;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<script>
|
||||||
|
import {useUserStore} from "../store/auth.js";
|
||||||
|
import {useComputersStore} from "../store/computers.js";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "JobsList",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
userStore: useUserStore(),
|
||||||
|
computersStore: useComputersStore(),
|
||||||
|
computerId: null,
|
||||||
|
fetching: false,
|
||||||
|
authenticated: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.computerId = this.$route.query.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<router-link to="/">
|
||||||
|
<v-btn color="#F0A068FF">Назад</v-btn>
|
||||||
|
</router-link>
|
||||||
|
<v-skeleton-loader v-if="fetching" color="grey-darken-3" class="w-100" type="card"/>
|
||||||
|
<div v-if="!fetching">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,14 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="w-100 h-100 d-flex justify-center">
|
<div class="w-100 h-100 d-flex justify-center">
|
||||||
<div class="d-flex flex-column align-center justify-center h-100 w-75">
|
<div class="d-flex flex-column justify-center h-100" :class="isWide ? 'w-50' : 'w-75'">
|
||||||
<v-form class="d-flex flex-column justify-center h-100 flex-grow-1" :class="isWide ? 'w-50' : 'w-75'" @submit.prevent="login">
|
<v-form @submit.prevent="login">
|
||||||
<v-label>Email:</v-label>
|
<v-label>Логин:</v-label>
|
||||||
<v-text-field type="email" v-model="email" label="E-mail" class="flex-grow-0" required></v-text-field>
|
<v-text-field type="email" v-model="email" label="E-mail" class="flex-grow-0" required></v-text-field>
|
||||||
<v-label>Пароль:</v-label>
|
<v-label>Пароль:</v-label>
|
||||||
<v-text-field type="password" v-model="password" label="Пароль" class="flex-grow-0" required></v-text-field>
|
<v-text-field type="password" v-model="password" label="Пароль" class="flex-grow-0" required></v-text-field>
|
||||||
<div class="d-flex justify-center align-center" :class="isWide ? '' : 'flex-column align-center'">
|
<v-checkbox v-model="rememberMe" label="Запомнить меня"></v-checkbox>
|
||||||
<v-btn type="submit" color="#F0A068FF" class="ma-5 min-width-btn flex-grow-0" :class="isWide ? 'w-25' : 'w-100 text-body-1'" block>Войти</v-btn>
|
<div class="d-flex justify-center" :class="isWide ? '' : 'flex-column align-center'">
|
||||||
<router-link to="/register" class="text-decoration-none link-no-color ma-5 flex-grow-0" :class="isWide ? 'w-25' : 'w-100'">
|
<!--<div>-->
|
||||||
|
<v-btn type="submit" color="#F0A068FF" class="ma-5 flex-grow-0" :class="isWide ? 'w-25' : 'w-100 text-body-1'" :loading="loading">Войти</v-btn>
|
||||||
|
<!--</div>-->
|
||||||
|
<router-link to="/register" class="text-decoration-none link-no-color ma-5" :class="isWide ? 'w-25' : 'w-100'">
|
||||||
<v-btn color="#F0A068FF" :class="isWide ? 'w-100' : 'w-100 text-body-1'">Регистрация</v-btn>
|
<v-btn color="#F0A068FF" :class="isWide ? 'w-100' : 'w-100 text-body-1'">Регистрация</v-btn>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,7 +32,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { useAuthStore } from '../store/auth.js';
|
import { useUserStore } from '../store/auth.js';
|
||||||
export default {
|
export default {
|
||||||
name: "Login",
|
name: "Login",
|
||||||
props: {
|
props: {
|
||||||
|
@ -37,16 +40,33 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
userStore: useUserStore(),
|
||||||
email: '',
|
email: '',
|
||||||
password: '',
|
password: '',
|
||||||
|
rememberMe: false,
|
||||||
|
loading: false,
|
||||||
|
errorMessage: '',
|
||||||
|
errorMessageContainerStyle: 'display: none;'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async login() {
|
async login() {
|
||||||
const authStore = useAuthStore();
|
this.loading = true;
|
||||||
await authStore.login({
|
await this.userStore.login(this.email, this.password, this.rememberMe).then((isLogged)=>{
|
||||||
email: this.email,
|
this.loading = false;
|
||||||
password: this.password,
|
if (typeof isLogged == "boolean") {
|
||||||
|
if (isLogged){
|
||||||
|
this.errorMessage = '';
|
||||||
|
this.errorMessageContainerStyle = 'display: none;';
|
||||||
|
this.$router.push('/');
|
||||||
|
} else {
|
||||||
|
this.errorMessage = 'Authentication error';
|
||||||
|
this.errorMessageContainerStyle = '';
|
||||||
|
}
|
||||||
|
} else if (typeof isLogged == "string") {
|
||||||
|
this.errorMessage = isLogged;
|
||||||
|
this.errorMessageContainerStyle = '';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.$router.push('/');
|
this.$router.push('/');
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { useAuthStore } from '../store/auth.js';
|
import { useUserStore } from '../store/auth.js';
|
||||||
export default {
|
export default {
|
||||||
name: "Register",
|
name: "Register",
|
||||||
props: {
|
props: {
|
||||||
|
@ -7,20 +7,39 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
userStore: useUserStore(),
|
||||||
name: '',
|
name: '',
|
||||||
email: '',
|
email: '',
|
||||||
password: '',
|
password: '',
|
||||||
|
c_password: '',
|
||||||
|
errorMessage: '',
|
||||||
|
errorMessageContainerStyle: 'display: none;',
|
||||||
|
showPassword: false,
|
||||||
|
showRepeatPassword: false,
|
||||||
|
loading: false
|
||||||
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async register() {
|
async register() {
|
||||||
const authStore = useAuthStore();
|
this.loading = true;
|
||||||
await authStore.register({
|
await this.userStore.registration(this.name, this.email, this.password, this.c_password).then((isRegistred)=>{
|
||||||
name: this.name,
|
this.loading = false;
|
||||||
email: this.email,
|
if (typeof isRegistred == "boolean") {
|
||||||
password: this.password,
|
if (isRegistred){
|
||||||
|
this.errorMessage = '';
|
||||||
|
this.errorMessageContainerStyle = 'display: none;';
|
||||||
|
this.$router.push('/');
|
||||||
|
} else {
|
||||||
|
this.errorMessage = 'Registration error';
|
||||||
|
this.errorMessageContainerStyle = '';
|
||||||
|
}
|
||||||
|
} else if (typeof isRegistred == "string") {
|
||||||
|
this.errorMessage = isRegistred;
|
||||||
|
this.errorMessageContainerStyle = '';
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
this.$router.push('/');
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,9 +55,11 @@ export default {
|
||||||
<v-text-field type="email" v-model="email" label="E-mail" class="flex-grow-0" required></v-text-field>
|
<v-text-field type="email" v-model="email" label="E-mail" class="flex-grow-0" required></v-text-field>
|
||||||
<v-label>Пароль:</v-label>
|
<v-label>Пароль:</v-label>
|
||||||
<v-text-field type="password" v-model="password" label="Пароль" class="flex-grow-0" required></v-text-field>
|
<v-text-field type="password" v-model="password" label="Пароль" class="flex-grow-0" required></v-text-field>
|
||||||
|
<v-text-field type="password" v-model="c_password" label="Повторите пароль" class="flex-grow-0" required></v-text-field>
|
||||||
|
<v-label :style="errorMessageContainerStyle">{{ errorMessage }}</v-label>
|
||||||
<div class="d-flex justify-center" :class="isWide ? '' : 'flex-column align-center'">
|
<div class="d-flex justify-center" :class="isWide ? '' : 'flex-column align-center'">
|
||||||
<v-btn type="submit" color="#F0A068FF" class="ma-5 min-width-btn flex-grow-0" :class="isWide ? 'w-25' : 'w-100 text-body-1'" block>Зарегистрироваться</v-btn>
|
<v-btn type="submit" color="#F0A068FF" class="ma-5" :class="isWide ? 'w-25' : 'w-100 text-body-1'" :loading="loading">Зарегистрироваться</v-btn>
|
||||||
<router-link to="/login" class="text-decoration-none link-no-color ma-5 flex-grow-0" :class="isWide ? 'w-25' : 'w-100'">
|
<router-link to="/login" class="text-decoration-none link-no-color ma-5" :class="isWide ? 'w-25' : 'w-100'">
|
||||||
<v-btn color="#F0A068FF" :class="isWide ? 'w-100' : 'w-100 text-body-1'">Вход</v-btn>
|
<v-btn color="#F0A068FF" :class="isWide ? 'w-100' : 'w-100 text-body-1'">Вход</v-btn>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<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">
|
||||||
|
<link rel="icon" href="images/favicon.svg" sizes="any" type="image/svg+xml">
|
||||||
<title>Журнал ТО</title>
|
<title>Журнал ТО</title>
|
||||||
@vite('resources/app.js')
|
@vite('resources/app.js')
|
||||||
@vite('resources/css/app.css')
|
@vite('resources/css/app.css')
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Http\Controllers\API\AuthController;
|
use App\Http\Controllers\API\AuthController;
|
||||||
|
use App\Http\Controllers\ComputerController;
|
||||||
|
use App\Http\Controllers\JobController;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
@ -19,6 +21,31 @@ Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
|
||||||
return $request->user();
|
return $request->user();
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::post('/register', [AuthController::class, 'register']);
|
Route::group(['prefix' => 'auth'], function () {
|
||||||
Route::post('/login', [AuthController::class, 'login']);
|
Route::post('login', [AuthController::class, 'login']);
|
||||||
Route::post('/logout', [AuthController::class, 'logout'])->middleware('auth:sanctum');
|
Route::post('register', [AuthController::class, 'register']);
|
||||||
|
|
||||||
|
Route::group(['middleware' => 'auth:sanctum'], function() {
|
||||||
|
Route::get('logout', [AuthController::class, 'logout']);
|
||||||
|
Route::get('user', [AuthController::class, 'user']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::group(['prefix' => 'data'], function () {
|
||||||
|
Route::group(['middleware' => 'auth:sanctum'], function() {
|
||||||
|
Route::group(['prefix' => 'computers'], function () {
|
||||||
|
Route::get('all', [ComputerController::class, 'index']);
|
||||||
|
Route::get('byUser', [ComputerController::class, 'getByUserId']);
|
||||||
|
Route::post('create', [ComputerController::class, 'create']);
|
||||||
|
Route::post('save', [ComputerController::class, 'update']);
|
||||||
|
Route::post('delete', [ComputerController::class, 'destroy']);
|
||||||
|
});
|
||||||
|
Route::group(['prefix' => 'jobs'], function () {
|
||||||
|
Route::get('all', [JobController::class, 'index']);
|
||||||
|
Route::get('byComputer', [JobController::class, 'getByComputerId']);
|
||||||
|
Route::post('create', [JobController::class, 'create']);
|
||||||
|
Route::post('save', [JobController::class, 'update']);
|
||||||
|
Route::post('delete', [JobController::class, 'destroy']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue