From 0fdd2cf7e04d0bc6559881810ea26cded66de273 Mon Sep 17 00:00:00 2001
From: "p.belezov"
Date: Mon, 28 Oct 2024 16:36:45 +0800
Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?=
=?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B2=D1=83=D1=8E=20=D0=B2=D0=B5=D1=80=D1=81?=
=?UTF-8?q?=D0=B8=D1=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/Http/Controllers/AuthController.php | 10 ++
app/Http/Controllers/WishesController.php | 25 ++++-
resources/PublicApp.vue | 16 +++
resources/css/app.css | 12 +++
resources/js/rules.js | 6 ++
resources/publicWishlist.js | 19 ++++
resources/store/user.js | 14 +++
resources/store/wish.js | 35 ++++++-
resources/views/Auth/Login.vue | 7 +-
resources/views/Auth/Registration.vue | 7 +-
resources/views/Public.vue | 36 +++++++
.../views/PublicWishlist/ShowWhishlist.vue | 54 ++++++++++
resources/views/Welcome.vue | 8 +-
resources/views/Wishlist/CreateWish.vue | 27 ++++-
resources/views/Wishlist/EditWish.vue | 99 +++++++++++++++++++
resources/views/Wishlist/Wishlist.vue | 91 ++++++++++-------
resources/views/public.blade.php | 14 +++
routes/api.php | 2 +
routes/web.php | 4 +
vite.config.js | 2 +-
20 files changed, 440 insertions(+), 48 deletions(-)
create mode 100644 resources/PublicApp.vue
create mode 100644 resources/publicWishlist.js
create mode 100644 resources/views/Public.vue
create mode 100644 resources/views/PublicWishlist/ShowWhishlist.vue
create mode 100644 resources/views/Wishlist/EditWish.vue
create mode 100644 resources/views/public.blade.php
diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php
index d4ae7ea..920c336 100644
--- a/app/Http/Controllers/AuthController.php
+++ b/app/Http/Controllers/AuthController.php
@@ -92,6 +92,16 @@ class AuthController extends Controller
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)
*
diff --git a/app/Http/Controllers/WishesController.php b/app/Http/Controllers/WishesController.php
index 5587251..4807846 100644
--- a/app/Http/Controllers/WishesController.php
+++ b/app/Http/Controllers/WishesController.php
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Wish;
+use App\Models\User;
class WishesController extends Controller
{
@@ -12,6 +13,19 @@ class WishesController extends Controller
return Wish::select('id', 'name', 'price', 'url')->where('user_id', '=', $user_id)->get();
}
+ public function getUsername(Request $request){
+ $request->validate([
+ 'user_id' => 'required|exists:users,id'
+ ]);
+ $username = ['username' => User::find($request->get('user_id'))['name']];
+ return response()->json($username, 201);
+ }
+
+ public function getWishById(Request $request, string $id)
+ {
+ return Wish::select('id', 'name', 'price', 'url')->where('id', '=', $id)->get();
+ }
+
public function create(Request $request)
{
$request->validate([
@@ -25,15 +39,20 @@ class WishesController extends Controller
return response()->json($wish, 201);
}
- public function update(Request $request, Wish $wish)
+ public function update(Request $request)
{
$request->validate([
+ 'id' => 'required|exists:wishes,id',
+ 'user_id' => 'required|exists:users,id',
'name' => 'required|string|max:256',
'price' => 'nullable|numeric',
'url' => 'nullable|url',
]);
-
- $wish->update($request->all());
+ $wish = Wish::find($request->get('id'));
+ $wish->name = $request->get('name');
+ $wish->price = $request->get('price');
+ $wish->url = $request->get('url');
+ $wish->save();
return response()->json($wish);
}
diff --git a/resources/PublicApp.vue b/resources/PublicApp.vue
new file mode 100644
index 0000000..a20baa0
--- /dev/null
+++ b/resources/PublicApp.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/resources/css/app.css b/resources/css/app.css
index d82198a..0dfedfd 100644
--- a/resources/css/app.css
+++ b/resources/css/app.css
@@ -16,3 +16,15 @@
background-color: #212022!important;
color: white!important;
}
+
+a:link {
+ color: aqua;
+}
+
+a:visited {
+ color: darkorange;
+}
+
+a:active {
+ color: crimson;
+}
\ No newline at end of file
diff --git a/resources/js/rules.js b/resources/js/rules.js
index f91263d..12d5fd1 100644
--- a/resources/js/rules.js
+++ b/resources/js/rules.js
@@ -5,5 +5,11 @@ export const rules = {
},
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) || 'Стоимость должна быть числом';
}
}
diff --git a/resources/publicWishlist.js b/resources/publicWishlist.js
new file mode 100644
index 0000000..ebad752
--- /dev/null
+++ b/resources/publicWishlist.js
@@ -0,0 +1,19 @@
+import './js/bootstrap';
+import {createApp} from 'vue'
+import PublicApp from './PublicApp.vue';
+import { createVuetify } from 'vuetify'
+import 'vuetify/styles'
+import * as components from 'vuetify/components'
+import * as directives from 'vuetify/directives'
+import '@mdi/font/css/materialdesignicons.css'
+import { createMemoryHistory, createRouter } from 'vue-router'
+import {createPinia} from "pinia";
+
+const vuetify = createVuetify({
+ components,
+ directives
+})
+
+const pinia = createPinia()
+
+createApp(PublicApp).use(vuetify).use(pinia).mount("#app")
diff --git a/resources/store/user.js b/resources/store/user.js
index 29eae75..6fa0eb2 100644
--- a/resources/store/user.js
+++ b/resources/store/user.js
@@ -82,6 +82,20 @@ export const useUserStore = defineStore('user', {
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;
}
},
})
diff --git a/resources/store/wish.js b/resources/store/wish.js
index 7d53ba6..493b4be 100644
--- a/resources/store/wish.js
+++ b/resources/store/wish.js
@@ -57,6 +57,39 @@ export const useWishStore = defineStore('wish', {
).then((response)=>{
return response;
});
- }
+ },
+ async update(id, user_id, name, price, url, token){
+ await axios.post(`/api/wish/update`,
+ {
+ id: id,
+ user_id: user_id,
+ name: name,
+ price: price,
+ url: url
+ },
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ token: token
+ },
+ }
+ ).then((response)=>{
+ return response;
+ });
+ },
+ async getWishById(id, token){
+ let result = null;
+ await axios.get(`/api/wish/by_id/${id.toString()}`,
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ token: token
+ }
+ }
+ ).then((response)=>{
+ result = response.data;
+ });
+ return result;
+ },
},
})
diff --git a/resources/views/Auth/Login.vue b/resources/views/Auth/Login.vue
index adff294..d474e12 100644
--- a/resources/views/Auth/Login.vue
+++ b/resources/views/Auth/Login.vue
@@ -17,7 +17,8 @@ export default {
rememberMe: false,
errorMessage: '',
errorMessageContainerStyle: '',
- showPassword: false
+ showPassword: false,
+ loading: false
}),
methods: {
validate(){
@@ -32,12 +33,14 @@ export default {
}
},
loginAction(){
+ this.loading = true;
let validation = this.validate();
if (validation !== true){
alert(validation);
return;
}
this.userStore.login(this.email, this.password, this.rememberMe).then((isLogged) => {
+ this.loading = false;
if (typeof isLogged == "boolean") {
if (isLogged){
this.errorMessage = '';
@@ -83,7 +86,7 @@ export default {
{{ errorMessage }}
- Войти
+ Войти
diff --git a/resources/views/Auth/Registration.vue b/resources/views/Auth/Registration.vue
index 7cfa62c..5f382f6 100644
--- a/resources/views/Auth/Registration.vue
+++ b/resources/views/Auth/Registration.vue
@@ -14,7 +14,8 @@ export default {
errorMessage: '',
errorMessageContainerStyle: 'display: none;',
showPassword: false,
- showRepeatPassword: false
+ showRepeatPassword: false,
+ loading: false
}),
computed: {
rules() {
@@ -37,12 +38,14 @@ export default {
return check === null ? true : check;
},
registrationAction(){
+ this.loading = true;
let validation = this.validate();
if (validation !== true){
alert(validation);
return;
}
this.userStore.registration(this.login, this.email, this.password, this.repeatPassword).then((isRegistred)=>{
+ this.loading = false;
if (typeof isRegistred == "boolean") {
if (isRegistred){
this.errorMessage = '';
@@ -100,7 +103,7 @@ export default {
required
>
{{ errorMessage }}
- Регистрация
+ Регистрация
diff --git a/resources/views/Public.vue b/resources/views/Public.vue
new file mode 100644
index 0000000..48520a5
--- /dev/null
+++ b/resources/views/Public.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/views/PublicWishlist/ShowWhishlist.vue b/resources/views/PublicWishlist/ShowWhishlist.vue
new file mode 100644
index 0000000..b5a7040
--- /dev/null
+++ b/resources/views/PublicWishlist/ShowWhishlist.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+ Список пользователя {{ this.username }} |
+
+
+ Наименование |
+ Цена |
+ Ссылка |
+
+
+
+
+ {{ wish['name'] }} |
+ {{ wish['price'] }} |
+ {{ wish['url'] }} |
+
+
+
+
+
+
diff --git a/resources/views/Welcome.vue b/resources/views/Welcome.vue
index c197459..2d9b985 100644
--- a/resources/views/Welcome.vue
+++ b/resources/views/Welcome.vue
@@ -12,7 +12,8 @@
Выйти
-
+
+
@@ -26,7 +27,8 @@ export default {
name: "Welcome",
data: () => ({
isAuthenticated: false,
- userStore: useUserStore()
+ userStore: useUserStore(),
+ fetchingUser: false
}),
computed: {
user() {
@@ -40,9 +42,11 @@ export default {
}
},
mounted() {
+ this.fetchingUser = true;
this.$router.push('/auth_options');
watch(this.userStore, (newStore, oldStore)=>{
this.isAuthenticated = newStore.user !== null && newStore.user !== undefined;
+ this.fetchingUser = false;
if (this.isAuthenticated) {
this.$router.push('/wishlist');
} else {
diff --git a/resources/views/Wishlist/CreateWish.vue b/resources/views/Wishlist/CreateWish.vue
index 262c491..e67e0ed 100644
--- a/resources/views/Wishlist/CreateWish.vue
+++ b/resources/views/Wishlist/CreateWish.vue
@@ -9,7 +9,8 @@ export default {
wishStore: useWishStore(),
name: null,
price: null,
- url: null
+ url: null,
+ creating: false
}),
computed: {
rules() {
@@ -22,15 +23,33 @@ export default {
},
methods: {
validate(){
- return rules.notNull(this.name);
+ if (this.price == ''){
+ this.price = null;
+ }
+ if (typeof this.price == 'string' && /^\d+[\.,\,]?\d+$/.test(this.price)){
+ this.price = parseFloat(this.price)
+ }
+ let validateName = rules.notNull(this.name);
+ let validatePrice = rules.price(this.price);
+ let check = null;
+ let valid = [validateName, validatePrice];
+ valid.forEach((element)=>{
+ if (typeof element !== "boolean"){
+ check = element;
+ }
+ });
+ return check === null ? true : check;
},
createWish(){
+ this.creating = true;
let validation = this.validate();
- if (typeof validation !== "boolean"){
+ if (typeof validation !== "boolean"){
+ this.creating = false;
alert(validation);
return;
}
this.wishStore.create(this.userStore.user['id'], this.name, this.price, this.url, this.userStore.token).then(()=>{
+ this.creating = false;
this.updateFrontWishes();
this.dialogCreate();
});
@@ -51,7 +70,7 @@ export default {
- Создать
+ Создать
diff --git a/resources/views/Wishlist/EditWish.vue b/resources/views/Wishlist/EditWish.vue
new file mode 100644
index 0000000..1557898
--- /dev/null
+++ b/resources/views/Wishlist/EditWish.vue
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+ Редактирование элемента
+
+
+
+
+
+
+
+
+ Сохранить
+
+
+
+
+
diff --git a/resources/views/Wishlist/Wishlist.vue b/resources/views/Wishlist/Wishlist.vue
index 01191b1..503c89a 100644
--- a/resources/views/Wishlist/Wishlist.vue
+++ b/resources/views/Wishlist/Wishlist.vue
@@ -3,20 +3,25 @@ import {useUserStore} from "../../store/user.js";
import {useWishStore} from "../../store/wish.js";
import CreateWish from "./CreateWish.vue";
import {ref} from "vue";
+import EditWish from "./EditWish.vue";
export default {
name: "Wishlist",
- components: {CreateWish},
+ components: {EditWish, CreateWish},
data: () => ({
userStore: useUserStore(),
wishStore: useWishStore(),
wishesList: [],
fetching: true,
dialogCreate: ref(false),
- dialogEdit: ref(false)
+ dialogEdit: ref(false),
+ wishToEditId: ref(0),
+ wishlistLink: '',
+ snackbar: false
}),
mounted() {
this.wishStore.getUserWishes(this.userStore.user['id']).then((wishes)=>{
this.wishesList = wishes;
+ this.wishlistLink = window.location.origin + '/wishlist/' + this.userStore.user['id'];
this.fetching = false
});
},
@@ -44,44 +49,64 @@ export default {
})
},
editWish(id){
-
+ this.wishToEditId = id;
+ this.dialogEdit = true;
},
- createWish(){
-
+ getWishToEditId(){
+ return this.wishToEditId;
+ },
+ copyLink(){
+ navigator.clipboard.writeText(this.wishlistLink);
+ this.snackbar = true;
}
}
}
-
-
-
-
-
- Наименование |
- Цена |
- Ссылка |
- |
- |
-
-
-
-
- {{ wish['name'] }} |
- {{ wish['price'] }} |
- {{ wish['url'] }} |
- |
- |
-
-
- |
-
-
-
-
-
-
+
+
+
+
+ {{ wishlistLink }}
+
+ Текст скопирован!
+
+
+
+
+ Наименование |
+ Цена |
+ Ссылка |
+ |
+ |
+
+
+
+
+ {{ wish['name'] }} |
+ {{ wish['price'] }} |
+ {{ wish['url'] }} |
+ |
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+
+