Skip to content

Commit

Permalink
Merge pull request #26 from shampiniony/register
Browse files Browse the repository at this point in the history
register user list and registration panel
  • Loading branch information
evsalik authored Jun 16, 2024
2 parents 1ae83e1 + 3ee88b8 commit 76758b8
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 24 deletions.
26 changes: 26 additions & 0 deletions src/api/register.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import axios from 'axios';
import { apiUrl } from '@/router/router';

interface RegisterResponse {
id: number;
}

interface RegisterData {
last_name: string;
first_name: string;
middle_name: string;
place: number;
phone_number: string;
email: string;
password: string;
}

export const registerUser = async (data: RegisterData): Promise<RegisterResponse> => {
try {
const response = await axios.post<RegisterResponse>(`${apiUrl}/api/v1/users/register/`, data);
return response.data;
} catch (error) {
console.error('Error during registration:', error);
throw new Error('Registration failed');
}
};
22 changes: 22 additions & 0 deletions src/api/userslist.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import axios from 'axios';
import { apiUrl } from '@/router/router';

interface User {
id: number;
last_name: string;
first_name: string;
middle_name: string;
place: number;
phone_number: string;
email: string;
}

export const getUsers = async (): Promise<User[]> => {
try {
const response = await axios.get<User[]>(`${apiUrl}/api/v1/users/`);
return response.data;
} catch (error) {
console.error('Error fetching users:', error);
throw new Error('Failed to fetch users');
}
};
3 changes: 3 additions & 0 deletions src/assets/icons/people.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/components/admin-header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<SidebarItem :imgSrc="profileIcon" to="/admin/profile" title="Профиль" :isOpen="isOpen" />
<SidebarItem :imgSrc="plusIcon" to="/admin/add-event" title="Добавить" :isOpen="isOpen" />
<SidebarItem :imgSrc="personPlus" to="/admin/registration" title="Регистрация" :isOpen="isOpen" />
<SidebarItem :imgSrc="people" to="/admin/userslist" title="Пользователи" :isOpen="isOpen" />

<button @click="toggleSidebar"
class="p-2 rounded-3xl bg-gray-200 absolute right-0 top-6 transform translate-x-1/2">
Expand All @@ -41,6 +42,7 @@ import plusIcon from '@/assets/icons/plus.icon.svg'
import SidebarItem from './sidebar-item.vue'
import logoIcon from '@/assets/logo.svg'
import personPlus from '@/assets/icons/personplus.svg'
import people from '@/assets/icons/people.svg'
import { useRoute, useRouter } from 'vue-router'
const isOpen = ref(false)
Expand Down
118 changes: 94 additions & 24 deletions src/pages/registration.page.vue
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
<template>
<div class="flex justify-center items-center h-screen bg-white">
<div class="bg-white p-8 rounded w-full max-w-sm ml-[200px]">
<div class="flex justify-center items-center min-h-screen bg-white w-[100%]">
<div class="bg-white p-8 rounded w-full max-w-lg mx-auto">
<h2 class="text-2xl font-bold mb-6 text-center">СОЗДАТЬ ПОЛЬЗОВАТЕЛЯ</h2>
<form>
<form @submit.prevent="submitForm">
<div class="mb-4">
<label class="block text-gray-700 mb-2" for="surname">ФАМИЛИЯ</label>
<input v-model="surname" type="text" id="surname" class="w-full px-3 py-2 border rounded" required>
<label class="block text-gray-700 mb-2" for="last_name">ФАМИЛИЯ</label>
<input v-model="last_name" type="text" id="last_name" class="w-full px-3 py-2 border rounded" required>
</div>
<div class="mb-6">
<label class="block text-gray-700 mb-2" for="name">ИМЯ</label>
<input v-model="name" type="text" id="name" class="w-full px-3 py-2 border rounded" required>
<div class="mb-4">
<label class="block text-gray-700 mb-2" for="first_name">ИМЯ</label>
<input v-model="first_name" type="text" id="first_name" class="w-full px-3 py-2 border rounded" required>
</div>
<div class="mb-8">
<label class="block text-gray-700 mb-2" for="patronymic">ОТЧЕСТВО</label>
<input v-model="patronymic" type="text" id="patronymic" class="w-full px-3 py-2 border rounded" required>
<div class="mb-4">
<label class="block text-gray-700 mb-2" for="middle_name">ОТЧЕСТВО</label>
<input v-model="middle_name" type="text" id="middle_name" class="w-full px-3 py-2 border rounded" required>
</div>
<div class="mb-10">
<label class="block text-gray-700 mb-2" for="location">МЕСТО</label>
<input v-model="password" type="password" id="location" class="w-full px-3 py-2 border rounded" required>
<div class="mb-4">
<label class="block text-gray-700 mb-2" for="place">МЕСТО</label>
<select v-model="place" id="place" class="w-full px-3 py-2 border rounded" required>
<option v-for="place in placesList" :key="place.id" :value="place.id">{{ place.name }}</option>
</select>
</div>
<div class="mb-12">
<label class="block text-gray-700 mb-2" for="password">ID</label>
<input v-model="password" type="password" id="password" class="w-full px-3 py-2 border rounded" required>
<div class="mb-4">
<label class="block text-gray-700 mb-2" for="phone_number">ТЕЛЕФОН</label>
<input v-model="phone_number" type="text" id="phone_number" class="w-full px-3 py-2 border rounded" required>
</div>
<div class="mb-14">
<label class="block text-gray-700 mb-2" for="password">ТЕЛЕФОН</label>
<input v-model="password" type="password" id="password" class="w-full px-3 py-2 border rounded" required>
<div class="mb-4">
<label class="block text-gray-700 mb-2" for="email">EMAIL</label>
<input v-model="email" type="email" id="email" class="w-full px-3 py-2 border rounded" required>
</div>
<div class="mb-16">
<label class="block text-gray-700 mb-2" for="password">EMAIL</label>
<div class="mb-6">
<label class="block text-gray-700 mb-2" for="password">ПАРОЛЬ</label>
<input v-model="password" type="password" id="password" class="w-full px-3 py-2 border rounded" required>
</div>
<button type="submit" class="w-full bg-logo-blue text-white py-2 rounded">ДОБАВИТЬ</button>
Expand All @@ -38,12 +40,80 @@
</template>

<script setup>
import { ref } from 'vue';
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { registerUser } from '@/api/register.api';
import getPlaces from '@/api/places.api';
import { places } from '@/store/places.store';
const last_name = ref('');
const first_name = ref('');
const middle_name = ref('');
const place = ref(null);
const phone_number = ref('');
const email = ref('');
const password = ref('');
const router = useRouter();
const placesList = ref([]);
onMounted(async () => {
try {
await getPlaces(new Date());
if (places.all) {
placesList.value = places.all;
console.log('Fetched places:', placesList.value);
} else {
console.error('Failed to fetch places');
}
} catch (error) {
console.error('Error fetching places:', error);
}
});
const submitForm = async () => {
console.log('Form submitted');
if (validateForm()) {
const userData = {
last_name: last_name.value,
first_name: first_name.value,
middle_name: middle_name.value,
place: place.value,
phone_number: phone_number.value,
email: email.value,
password: password.value,
};
console.log('Submitting user data:', userData);
try {
const response = await registerUser(userData);
console.log('User registered:', response);
} catch (error) {
console.error('Registration failed:', error.response ? error.response.data : error.message);
}
}
};
const validateForm = () => {
if (!last_name.value || !first_name.value || !middle_name.value || !place.value || !phone_number.value || !email.value || !password.value) {
alert('Пожалуйста, заполните все поля');
return false;
}
if (!validateEmail(email.value)) {
alert('Пожалуйста, введите действительный email');
return false;
}
return true;
};
const validateEmail = (email) => {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(String(email).toLowerCase());
};
</script>

<style scoped>
.bg-logo-blue {
background-color: #6193b1;
}
</style>
</style>
36 changes: 36 additions & 0 deletions src/pages/userslist.page.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<template>
<div class="flex justify-center items-center min-h-screen bg-white w-[100%]">
<div class="bg-white mt-5 p-8 rounded w-full max-w-lg mx-auto">
<h2 class="text-2xl font-bold mb-6 text-center">СПИСОК ПОЛЬЗОВАТЕЛЕЙ</h2>
<ul v-if="users.length > 0" class="list-disc pl-5">
<li v-for="user in users" :key="user.id" class="mb-2">
{{ user.last_name }} {{ user.first_name }} {{ user.middle_name }} - {{ user.email }} - {{ user.phone_number }}
</li>
</ul>
<p v-else>Пользователи не найдены</p>
</div>
</div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { getUsers } from '@/api/userslist.api';
const users = ref([]);
onMounted(async () => {
try {
const fetchedUsers = await getUsers();
users.value = fetchedUsers;
console.log('Fetched users:', users.value);
} catch (error) {
console.error('Error fetching users:', error);
}
});
</script>

<style scoped>
.bg-logo-blue {
background-color: #6193b1;
}
</style>
6 changes: 6 additions & 0 deletions src/router/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import BookingPage from '@/pages/booking.page.vue';
import BillingsPage from '@/pages/billings.page.vue';
import LoginPage from '@/pages/login.page.vue';
import Registration from '@/pages/registration.page.vue';
import UsersList from '@/pages/userslist.page.vue';

import { createRouter, createWebHistory } from 'vue-router';

Expand Down Expand Up @@ -76,6 +77,11 @@ const routes = [
path: 'registration',
name: 'Registration',
component: Registration,
},
{
path: 'userslist',
name: 'UsersList',
component: UsersList,
}
],
},
Expand Down

0 comments on commit 76758b8

Please sign in to comment.