add change status buttons

This commit is contained in:
2026-07-26 00:22:30 +07:00
parent e7b7c1180b
commit 93b131dbca
11 changed files with 790 additions and 656 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -5,8 +5,8 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Вечерний детектив</title>
<script type="module" crossorigin src="/assets/index-CGIEdu3F.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-RcOLieKE.css">
<script type="module" crossorigin src="/assets/index-Cse9kYPG.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DwS7oaRt.css">
</head>
<body>
<div id="app"></div>
+43 -4
View File
@@ -240,6 +240,28 @@ service EveningDetectiveServer {
};
}
rpc PublicScenario(PublicScenarioReq) returns (PublicScenarioRsp) {
option (google.api.http) = {
put : "/api/scenarios/{id}/public"
body: "*"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
tags : "Сценарии";
summary: "Опубликовать сценарий";
};
}
rpc DraftScenario(DraftScenarioReq) returns (DraftScenarioRsp) {
option (google.api.http) = {
put : "/api/scenarios/{id}/draft"
body: "*"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
tags : "Сценарии";
summary: "Снять с публикации сценарий";
};
}
rpc DeleteScenario(DeleteScenarioReq) returns (DeleteScenarioRsp) {
option (google.api.http) = {
delete: "/api/scenarios/{id}"
@@ -435,10 +457,11 @@ message Scenario {
optional string description = 3;
optional string image = 4;
Story story = 5;
User author = 6;
google.protobuf.Timestamp updated_at = 7;
google.protobuf.Timestamp created_at = 8;
google.protobuf.Timestamp published_at = 9;
string status = 6;
User author = 7;
google.protobuf.Timestamp updated_at = 8;
google.protobuf.Timestamp created_at = 9;
google.protobuf.Timestamp published_at = 10;
}
message Story {
@@ -482,6 +505,22 @@ message UpdateScenarioRsp {
string error = 1;
}
message PublicScenarioReq {
int32 id = 1;
}
message PublicScenarioRsp {
string error = 1;
}
message DraftScenarioReq {
int32 id = 1;
}
message DraftScenarioRsp {
string error = 1;
}
message DeleteScenarioReq {
int32 id = 1;
}
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -17,11 +17,12 @@
--vt-c-text-dark-2: rgb(235 235 235 / 64%);
/* Главный цвет */
--main-color: rgba(34, 50, 60, 1);
--main-color: rgb(34 50 60 / 100%);
/* --second-color: rgb(97, 74, 22); */
--second-color: burlywood;
--main-back-color: rgba(240, 240, 240, 1);
--main-back-item-color: rgba(254, 254, 254, 1);
--main-back-color: rgb(240 240 240 / 100%);
--main-back-item-color: rgb(254 254 254 / 100%);
}
/* semantic color variables for this project */
-2
View File
@@ -96,9 +96,7 @@ const openMenu = ref(false)
left: 0;
width: 100%;
height: 70px;
background-color: #222;
padding: 20px;
display: flex;
justify-content: space-between;
+1 -1
View File
@@ -39,7 +39,7 @@
background-image: url("@/assets/images/paper.jpg");
background-size: cover;
display: flow-root;
box-shadow: 0px 0 5px black;
box-shadow: 0 0 5px black;
}
.message-cloud-2,
+7 -5
View File
@@ -1,9 +1,10 @@
<script setup lang="ts">
import { NDynamicInput, NInput, NInputGroup, NSpace, NSwitch, NText, NUpload, NUploadDragger, NButton } from 'naive-ui'
import type { PropType } from 'vue'
import { Key24Regular } from '@vicons/fluent'
import { LockOutlined } from '@vicons/material'
import { Icon } from '@vicons/utils'
import { Key24Regular } from '@vicons/fluent'
import { NButton,NDynamicInput, NInput, NInputGroup, NSpace, NSwitch, NText, NUpload, NUploadDragger } from 'naive-ui'
import type { PropType } from 'vue'
import type { Application, Door, Key, Place } from '@/api/generated/crabs/evening_detective_server'
const props = defineProps({
@@ -230,6 +231,7 @@ function onCreateKey(): Key {
.hr {
margin: 10px 0;
border: dashed 1px;
/* border-color: black; */
border-color: #eee;
}
@@ -304,7 +306,7 @@ function onCreateKey(): Key {
.need-keys-text {
color: gold;
margin: 15px 0 0 0;
margin: 15px 0 0;
padding: 0;
}
@@ -335,7 +337,7 @@ function onCreateKey(): Key {
margin-right: 15px;
background-image: url("@/assets/images/paper_white.jpg");
background-size: cover;
box-shadow: 0px 3px 15px rgb(98, 98, 98);
box-shadow: 0 3px 15px rgb(98 98 98);
transform: rotate(-3deg);
}
+51 -2
View File
@@ -2,7 +2,7 @@
import { Settings } from '@vicons/carbon'
import { Icon } from '@vicons/utils'
import { NButton, type UploadFileInfo, useMessage } from 'naive-ui'
import { NCard, NFlex, NInput, NModal, NSpace, NText, NUpload, NUploadDragger } from 'naive-ui'
import { NCard, NFlex, NInput, NModal, NSpace, NText, NUpload, NUploadDragger, NAlert } from 'naive-ui'
import { ref } from 'vue'
import { useRoute } from 'vue-router'
@@ -17,6 +17,7 @@ const route = useRoute()
const scenarioId = route.params.id
const showSettingsScenarioModal = ref(false)
const statusScenarioName = ref('')
const deletedScenarioName = ref('')
const message = useMessage()
@@ -56,6 +57,30 @@ async function deleteScenario(id: number) {
router.push('/scenarios')
}
async function publicScenario(id: number) {
const res = await client.PublicScenario({ id: id })
if (res.error != '') {
message.error(res.error!)
return
}
await getScenario(Number(scenarioId))
statusScenarioName.value = ''
showSettingsScenarioModal.value = false
}
async function draftScenario(id: number) {
const res = await client.DraftScenario({ id: id })
if (res.error != '') {
message.error(res.error!)
return
}
await getScenario(Number(scenarioId))
statusScenarioName.value = ''
showSettingsScenarioModal.value = false
}
async function uploadFile(file: File | null, filename: string): Promise<string> {
if (!file) {
return ''
@@ -152,7 +177,7 @@ async function cancelAddPlace() {
async function addNotFoundDoors(scenario: Scenario, place: Place) {
for (const door of place.doors || []) {
let place = scenario.story?.places?.find((place) => {
const place = scenario.story?.places?.find((place) => {
return place.code == door.code
})
if (place == undefined) {
@@ -227,6 +252,11 @@ async function deletePlace(place: Place) {
<template>
<div class="center-block-custom-big">
<div class="places-container">
<n-alert v-if="scenario.status == 'public'" title="Сценарий опубликован" type="warning"
style="margin-bottom: 20px;">
Не рекомендуется редактировать сценарий когда он опубликован.
</n-alert>
<div class="settings-block">
Точек: {{ scenario.story?.places?.length }}
<n-button quaternary @click="showSettingsScenarioModal = true" class="settings-button">
@@ -282,6 +312,25 @@ async function deletePlace(place: Place) {
<n-button @click="updateScenario()" ghost> Сохранить изменения </n-button>
<hr class="settings-hr" />
<p>Публикация</p>
<p>Статус:
<span v-if="scenario.status == 'public'">опубликовано</span>
<span v-if="scenario.status == 'draft'">в разработке</span>
</p>
<p>
Введите название сценария <n-text class="name-text" strong>{{ scenario.name }}</n-text>
</p>
<n-input v-model:value="statusScenarioName" type="text" placeholder='Дело №0 "Следствие ведут овечки"' />
<n-button v-if="scenario.status != 'public'" @click="publicScenario(scenario.id!)" ghost
:disabled="statusScenarioName != scenario.name">
Опубликовать сценарий
</n-button>
<n-button v-if="scenario.status != 'draft'" @click="draftScenario(scenario.id!)" ghost
:disabled="statusScenarioName != scenario.name">
Снять сценарий с публикации
</n-button>
<hr class="settings-hr" />
<p>
+4 -3
View File
@@ -1,9 +1,10 @@
<script setup lang="ts">
import { NButton, NFlex,NSpace, NTag, useMessage } from 'naive-ui'
import { ref } from 'vue'
import { getAuthClient } from '@/api/auth_client'
import type { User } from '@/api/generated/crabs/evening_detective_server'
import HeaderMenu from '@/components/HeaderMenu.vue'
import { useMessage, NTable, NButton, NTag, NSpace, NFlex } from 'naive-ui'
import { ref } from 'vue'
const client = getAuthClient()
const message = useMessage()
@@ -86,7 +87,7 @@ async function deleteRole(userId: number, role: string) {
.user-block {
border: 1px solid #444;
border-radius: 10px;
margin: 0 0 20px 0;
margin: 0 0 20px;
padding: 20px;
}