Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

register user list and registration panel #26

Merged
merged 1 commit into from
Jun 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -42,6 +43,7 @@ import SidebarItem from './sidebar-item.vue'
import searchIcon from '@/assets/icons/search.icon.svg'
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
Loading