diff --git a/WEB/src/api/projects/createProject.js b/WEB/src/api/projects/createProject.js
new file mode 100644
index 0000000..abebdd5
--- /dev/null
+++ b/WEB/src/api/projects/createProject.js
@@ -0,0 +1,23 @@
+import axios from 'axios'
+import CONFIG from '@/core/config.js'
+
+const createProject = async (project) => {
+ try {
+ const token = localStorage.getItem('access_token') // или другой способ получения токена
+ const response = await axios.post(
+ `${CONFIG.BASE_URL}/projects`,
+ project,
+ {
+ withCredentials: true,
+ headers: {
+ Authorization: `Bearer ${token}`
+ }
+ }
+ )
+ return response.data
+ } catch (error) {
+ throw new Error(error.response?.data?.detail || error.message)
+ }
+}
+
+export default createProject
diff --git a/WEB/src/api/projects/deleteProject.js b/WEB/src/api/projects/deleteProject.js
new file mode 100644
index 0000000..0f5f03e
--- /dev/null
+++ b/WEB/src/api/projects/deleteProject.js
@@ -0,0 +1,22 @@
+import axios from 'axios'
+import CONFIG from '@/core/config.js'
+
+const deleteProject = async (projectId) => {
+ try {
+ const token = localStorage.getItem('access_token') // получение токена
+ const response = await axios.delete(
+ `${CONFIG.BASE_URL}/projects/${projectId}`,
+ {
+ withCredentials: true,
+ headers: {
+ Authorization: `Bearer ${token}`
+ }
+ }
+ )
+ return response.data
+ } catch (error) {
+ throw new Error(error.response?.data?.detail || error.message)
+ }
+}
+
+export default deleteProject
diff --git a/WEB/src/api/projects/getProjects.js b/WEB/src/api/projects/getProjects.js
index d0c5fdf..c3daf6d 100644
--- a/WEB/src/api/projects/getProjects.js
+++ b/WEB/src/api/projects/getProjects.js
@@ -3,13 +3,19 @@ import CONFIG from "@/core/config.js";
const fetchProjects = async () => {
try {
+ const token = localStorage.getItem("access_token");
const response = await axios.get(`${CONFIG.BASE_URL}/projects`, {
- withCredentials: true,
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
});
+
return response.data;
} catch (error) {
if (error.response?.status === 401) {
throw new Error("Нет доступа к проектам (401)");
+ } else if (error.response?.status === 403) {
+ throw new Error("Доступ запрещён (403)");
}
throw new Error(error.message);
}
diff --git a/WEB/src/api/projects/updateProject.js b/WEB/src/api/projects/updateProject.js
new file mode 100644
index 0000000..dee0132
--- /dev/null
+++ b/WEB/src/api/projects/updateProject.js
@@ -0,0 +1,31 @@
+import axios from 'axios'
+import CONFIG from '@/core/config.js'
+
+const updateProject = async (project) => {
+ try {
+ const token = localStorage.getItem('access_token')
+
+ // Убираем id из тела запроса, он идет в URL
+ const { id, ...projectData } = project
+
+ console.log('Отправляем на сервер:', projectData)
+
+ const response = await axios.put(
+ `${CONFIG.BASE_URL}/projects/${id}`,
+ projectData,
+ {
+ withCredentials: true,
+ headers: {
+ Authorization: `Bearer ${token}`
+ }
+ }
+ )
+
+ console.log('Ответ от сервера:', response.data)
+ return response.data
+ } catch (error) {
+ throw new Error(error.response?.data?.detail || error.message)
+ }
+}
+
+export default updateProject
diff --git a/WEB/src/api/teams/deleteTeam.js b/WEB/src/api/teams/deleteTeam.js
index 4203818..9a53cb3 100644
--- a/WEB/src/api/teams/deleteTeam.js
+++ b/WEB/src/api/teams/deleteTeam.js
@@ -3,9 +3,15 @@ import CONFIG from '@/core/config.js'
const deleteTeam = async (teamId) => {
try {
+ const token = localStorage.getItem('access_token') // получение токена
const response = await axios.delete(
`${CONFIG.BASE_URL}/teams/${teamId}`,
- { withCredentials: true }
+ {
+ withCredentials: true,
+ headers: {
+ Authorization: `Bearer ${token}`
+ }
+ }
)
return response.data
} catch (error) {
diff --git a/WEB/src/components/SharedDialogWrapper.vue b/WEB/src/components/SharedDialogWrapper.vue
new file mode 100644
index 0000000..ba28848
--- /dev/null
+++ b/WEB/src/components/SharedDialogWrapper.vue
@@ -0,0 +1,26 @@
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WEB/src/components/dialogs/ContestDialog.vue b/WEB/src/components/dialogs/ContestDialog.vue
new file mode 100644
index 0000000..bfb3c2f
--- /dev/null
+++ b/WEB/src/components/dialogs/ContestDialog.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WEB/src/components/dialogs/ProjectDialog.vue b/WEB/src/components/dialogs/ProjectDialog.vue
new file mode 100644
index 0000000..e3b1242
--- /dev/null
+++ b/WEB/src/components/dialogs/ProjectDialog.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WEB/src/components/dialogs/TeamDialog.vue b/WEB/src/components/dialogs/TeamDialog.vue
new file mode 100644
index 0000000..eec20ed
--- /dev/null
+++ b/WEB/src/components/dialogs/TeamDialog.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WEB/src/components/dialogs/UserDialog.vue b/WEB/src/components/dialogs/UserDialog.vue
new file mode 100644
index 0000000..9bfc80e
--- /dev/null
+++ b/WEB/src/components/dialogs/UserDialog.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WEB/src/pages/AdminPage.vue b/WEB/src/pages/AdminPage.vue
index eefb0f7..22f9df2 100644
--- a/WEB/src/pages/AdminPage.vue
+++ b/WEB/src/pages/AdminPage.vue
@@ -45,7 +45,7 @@
@@ -169,7 +169,7 @@
flat
label="Удалить"
color="negative"
- @click="deleteTeam"
+ @click="deleteItem"
/>
t.id === teamToUpdate.id)
- if (index !== -1) {
- teams.value[index] = JSON.parse(JSON.stringify(teamToUpdate))
- }
+ await updateTeam(dialogData.value)
+ const idx = teams.value.findIndex(t => t.id === dialogData.value.id)
+ if (idx !== -1) teams.value[idx] = JSON.parse(JSON.stringify(dialogData.value))
} else {
const newTeam = await createTeam(dialogData.value)
teams.value.push(newTeam)
}
- closeDialog()
- } catch (error) {
- console.error('Ошибка при сохранении:', error.message)
+ } else if (dialogType.value === 'projects') {
+ if (dialogData.value.id) {
+ await updateProject(dialogData.value)
+ const idx = projects.value.findIndex(p => p.id === dialogData.value.id)
+ if (idx !== -1) projects.value[idx] = JSON.parse(JSON.stringify(dialogData.value))
+ } else {
+ const newProject = await createProject(dialogData.value)
+ projects.value.push(newProject)
+ }
}
+ closeDialog()
+ } catch (error) {
+ console.error('Ошибка при сохранении:', error.message)
}
}
-
async function loadData(name) {
if (name === 'teams') {
loadingTeams.value = true
@@ -296,30 +309,37 @@ async function loadData(name) {
} finally {
loadingTeams.value = false
}
+ } else if (name === 'projects') {
+ loadingProjects.value = true
+ try {
+ projects.value = await fetchProjects() || []
+ } catch (error) {
+ projects.value = []
+ console.error(error.message)
+ } finally {
+ loadingProjects.value = false
+ }
}
- console.log('teams loaded:', teams.value)
}
-async function deleteTeam() {
+async function deleteItem() {
if (!dialogData.value.id) return
try {
- await deleteTeamById(dialogData.value.id)
- teams.value = teams.value.filter(t => t.id !== dialogData.value.id)
+ if (dialogType.value === 'teams') {
+ await deleteTeamById(dialogData.value.id)
+ teams.value = teams.value.filter(t => t.id !== dialogData.value.id)
+ } else if (dialogType.value === 'projects') {
+ await deleteProjectById(dialogData.value.id)
+ projects.value = projects.value.filter(p => p.id !== dialogData.value.id)
+ }
closeDialog()
} catch (error) {
- console.error('Ошибка при удалении команды:', error.message)
+ console.error('Ошибка при удалении:', error.message)
}
}
-function createTeamHandler() {
- dialogType.value = 'teams'
- dialogData.value = {
- title: '',
- description: '',
- logo: '',
- git_url: ''
- }
- dialogVisible.value = true
+function createHandler() {
+ openEdit(tab.value, null)
}
onMounted(() => {
@@ -350,4 +370,4 @@ watch(tab, (newTab) => {
background: #ede9fe;
box-shadow: 0 6px 32px rgba(124, 58, 237, 0.13), 0 1.5px 6px rgba(124, 58, 237, 0.10);
}
-
+
\ No newline at end of file