@mundogamernetwork/shared-ui 1.1.79 → 1.1.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/keys/KeyCampaignDashboardCard.vue +2 -2
- package/locales/de.json +16 -1
- package/locales/en.json +16 -1
- package/locales/pt-BR.json +16 -1
- package/locales/ro.json +16 -1
- package/package.json +1 -1
- package/pages/key-campaigns/redeem-key-approved.vue +1 -1
- package/pages/key-campaigns/redeem-key.vue +202 -65
|
@@ -250,7 +250,7 @@ const detailRoute = computed(() =>
|
|
|
250
250
|
top: 6px;
|
|
251
251
|
right: 6px;
|
|
252
252
|
background: var(--primary);
|
|
253
|
-
color: #
|
|
253
|
+
color: var(--key-accent-ink, #13161C);
|
|
254
254
|
font-size: 11px;
|
|
255
255
|
font-weight: 700;
|
|
256
256
|
padding: 2px 7px;
|
|
@@ -280,7 +280,7 @@ const detailRoute = computed(() =>
|
|
|
280
280
|
bottom: 6px;
|
|
281
281
|
left: 6px;
|
|
282
282
|
background: var(--primary);
|
|
283
|
-
color: #
|
|
283
|
+
color: var(--key-accent-ink, #13161C);
|
|
284
284
|
font-size: 10px;
|
|
285
285
|
font-weight: 700;
|
|
286
286
|
padding: 3px 7px;
|
package/locales/de.json
CHANGED
|
@@ -169,7 +169,22 @@
|
|
|
169
169
|
},
|
|
170
170
|
"status_label": "Status",
|
|
171
171
|
"error_no_keys": "Derzeit sind keine Schlüssel für diese Kampagne verfügbar.",
|
|
172
|
-
"error_not_approved": "Ihre Anfrage wurde noch nicht genehmigt."
|
|
172
|
+
"error_not_approved": "Ihre Anfrage wurde noch nicht genehmigt.",
|
|
173
|
+
"quantity": "Anzahl der Schlüssel",
|
|
174
|
+
"error_duplicate": "Sie haben bereits eine Anfrage für diese Kampagne. Überprüfen Sie 'Meine Bestellungen' für den Status.",
|
|
175
|
+
"error_user_blocked": "Ihr Zugang zu Key-Anfragen wurde vorübergehend gesperrt, da Material-Einreichungen überfällig sind. Bitte reichen Sie Ihre ausstehenden Materialien ein.",
|
|
176
|
+
"error_not_eligible": "Diese Kampagne ist für Ihren aktuellen Plan nicht verfügbar.",
|
|
177
|
+
"error_pending_limit": "Sie haben das gleichzeitige Anfragenlimit Ihres Plans erreicht. Bitte erfüllen Sie Ihre ausstehenden Verpflichtungen, bevor Sie einen neuen Key anfordern.",
|
|
178
|
+
"select_option": "Option auswählen",
|
|
179
|
+
"required_data": "Erforderliche Angaben",
|
|
180
|
+
"already_requested": "Sie haben bereits eine Anfrage für diese Kampagne gestellt.",
|
|
181
|
+
"back_to_campaign": "Zur Kampagne zurückkehren",
|
|
182
|
+
"status_pending": "Anfrage ausstehend — bitte warten Sie auf die Genehmigung",
|
|
183
|
+
"status_approved": "Anfrage genehmigt — Sie können jetzt Ihren Schlüssel abrufen",
|
|
184
|
+
"status_completed": "Anfrage abgeschlossen",
|
|
185
|
+
"status_refused": "Anfrage abgelehnt",
|
|
186
|
+
"status_cancelled": "Anfrage storniert",
|
|
187
|
+
"refused_reason": "Grund der Ablehnung:"
|
|
173
188
|
},
|
|
174
189
|
"materials": {
|
|
175
190
|
"title": "Submit material",
|
package/locales/en.json
CHANGED
|
@@ -169,7 +169,22 @@
|
|
|
169
169
|
},
|
|
170
170
|
"status_label": "Status",
|
|
171
171
|
"error_no_keys": "No keys available for this campaign at the moment.",
|
|
172
|
-
"error_not_approved": "Your request has not been approved yet."
|
|
172
|
+
"error_not_approved": "Your request has not been approved yet.",
|
|
173
|
+
"quantity": "Number of keys",
|
|
174
|
+
"error_duplicate": "You already have a request for this campaign. Check 'My Orders' to see the status.",
|
|
175
|
+
"error_user_blocked": "Your key request access has been temporarily blocked due to overdue material submissions. Please submit your pending materials to restore access.",
|
|
176
|
+
"error_not_eligible": "This campaign is not available for your current plan.",
|
|
177
|
+
"error_pending_limit": "You have reached the simultaneous request limit for your plan. Please fulfill your pending obligations before requesting a new key.",
|
|
178
|
+
"select_option": "Select an option",
|
|
179
|
+
"required_data": "Required data",
|
|
180
|
+
"already_requested": "You have already submitted a request for this campaign.",
|
|
181
|
+
"back_to_campaign": "Back to campaign",
|
|
182
|
+
"status_pending": "Request pending — waiting for approval",
|
|
183
|
+
"status_approved": "Request approved — you can now retrieve your key",
|
|
184
|
+
"status_completed": "Request completed",
|
|
185
|
+
"status_refused": "Request refused",
|
|
186
|
+
"status_cancelled": "Request cancelled",
|
|
187
|
+
"refused_reason": "Reason for refusal:"
|
|
173
188
|
},
|
|
174
189
|
"materials": {
|
|
175
190
|
"title": "Submit material",
|
package/locales/pt-BR.json
CHANGED
|
@@ -169,7 +169,22 @@
|
|
|
169
169
|
},
|
|
170
170
|
"status_label": "Status",
|
|
171
171
|
"error_no_keys": "Não há chaves disponíveis para esta campanha no momento.",
|
|
172
|
-
"error_not_approved": "Sua solicitação ainda não foi aprovada."
|
|
172
|
+
"error_not_approved": "Sua solicitação ainda não foi aprovada.",
|
|
173
|
+
"quantity": "Quantidade de chaves",
|
|
174
|
+
"error_duplicate": "Você já tem um pedido para esta campanha. Acesse 'Meus Pedidos' para ver o status.",
|
|
175
|
+
"error_user_blocked": "Seu acesso a pedidos de chave está temporariamente bloqueado por materiais não entregues. Envie seus materiais pendentes para restaurar o acesso.",
|
|
176
|
+
"error_not_eligible": "Esta campanha não está disponível para o seu plano atual.",
|
|
177
|
+
"error_pending_limit": "Você atingiu o limite de pedidos simultâneos do seu plano. Entregue o material pendente antes de solicitar uma nova chave.",
|
|
178
|
+
"select_option": "Selecione uma opção",
|
|
179
|
+
"required_data": "Dados obrigatórios",
|
|
180
|
+
"already_requested": "Você já enviou uma solicitação para esta campanha.",
|
|
181
|
+
"back_to_campaign": "Voltar para a campanha",
|
|
182
|
+
"status_pending": "Solicitação pendente — aguardando aprovação",
|
|
183
|
+
"status_approved": "Solicitação aprovada — você pode resgatar sua chave",
|
|
184
|
+
"status_completed": "Solicitação concluída",
|
|
185
|
+
"status_refused": "Solicitação recusada",
|
|
186
|
+
"status_cancelled": "Solicitação cancelada",
|
|
187
|
+
"refused_reason": "Motivo da recusa:"
|
|
173
188
|
},
|
|
174
189
|
"materials": {
|
|
175
190
|
"title": "Submit material",
|
package/locales/ro.json
CHANGED
|
@@ -169,7 +169,22 @@
|
|
|
169
169
|
},
|
|
170
170
|
"status_label": "Status",
|
|
171
171
|
"error_no_keys": "Nu există chei disponibile pentru această campanie în acest moment.",
|
|
172
|
-
"error_not_approved": "Cererea ta nu a fost aprobată încă."
|
|
172
|
+
"error_not_approved": "Cererea ta nu a fost aprobată încă.",
|
|
173
|
+
"quantity": "Numărul de chei",
|
|
174
|
+
"error_duplicate": "Aveți deja o cerere pentru această campanie. Verificați 'Comenzile mele' pentru status.",
|
|
175
|
+
"error_user_blocked": "Accesul dvs. la solicitările de chei a fost blocat temporar din cauza transmisiilor de materiale restante. Trimiteți materialele dvs. pentru a restabili accesul.",
|
|
176
|
+
"error_not_eligible": "Această campanie nu este disponibilă pentru planul dvs. actual.",
|
|
177
|
+
"error_pending_limit": "Ați atins limita de cereri simultane a planului dvs. Îndepliniți-vă obligațiile restante înainte de a solicita o nouă cheie.",
|
|
178
|
+
"select_option": "Selectează o opțiune",
|
|
179
|
+
"required_data": "Date obligatorii",
|
|
180
|
+
"already_requested": "Ați trimis deja o cerere pentru această campanie.",
|
|
181
|
+
"back_to_campaign": "Înapoi la campanie",
|
|
182
|
+
"status_pending": "Cerere în așteptare — așteptați aprobarea",
|
|
183
|
+
"status_approved": "Cerere aprobată — puteți prelua cheia",
|
|
184
|
+
"status_completed": "Cerere finalizată",
|
|
185
|
+
"status_refused": "Cerere refuzată",
|
|
186
|
+
"status_cancelled": "Cerere anulată",
|
|
187
|
+
"refused_reason": "Motivul refuzului:"
|
|
173
188
|
},
|
|
174
189
|
"materials": {
|
|
175
190
|
"title": "Submit material",
|
package/package.json
CHANGED
|
@@ -302,7 +302,7 @@ function goBack() {
|
|
|
302
302
|
font-size: 14px;
|
|
303
303
|
font-weight: 700;
|
|
304
304
|
background: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
305
|
-
color: #
|
|
305
|
+
color: var(--key-accent-ink, #13161C);
|
|
306
306
|
border: none;
|
|
307
307
|
cursor: pointer;
|
|
308
308
|
transition: opacity 0.15s;
|
|
@@ -35,6 +35,15 @@ const requestError = ref("")
|
|
|
35
35
|
const selectedPlatformId = ref<number | null>(null)
|
|
36
36
|
const selectedRegionId = ref<number | null>(null)
|
|
37
37
|
const description = ref("")
|
|
38
|
+
const quantity = ref<number | null>(1)
|
|
39
|
+
|
|
40
|
+
const maxKeysForUser = computed(() => campaign.value?.max_keys_for_user ?? 1)
|
|
41
|
+
|
|
42
|
+
function clampQuantity() {
|
|
43
|
+
if (quantity.value === null) return
|
|
44
|
+
if (quantity.value < 1) quantity.value = 1
|
|
45
|
+
if (quantity.value > maxKeysForUser.value) quantity.value = maxKeysForUser.value
|
|
46
|
+
}
|
|
38
47
|
|
|
39
48
|
onMounted(async () => {
|
|
40
49
|
if (!currentUser) {
|
|
@@ -63,9 +72,36 @@ onMounted(async () => {
|
|
|
63
72
|
})
|
|
64
73
|
|
|
65
74
|
const canSubmit = computed(() =>
|
|
66
|
-
!!selectedPlatformId.value && !!selectedRegionId.value && !submitting.value,
|
|
75
|
+
!!selectedPlatformId.value && !!selectedRegionId.value && !!quantity.value && !submitting.value,
|
|
67
76
|
)
|
|
68
77
|
|
|
78
|
+
// Collapsible "Required data" box — matches tv's original toggle behavior
|
|
79
|
+
const isBoxOpen = ref(true)
|
|
80
|
+
function toggleBox() {
|
|
81
|
+
isBoxOpen.value = !isBoxOpen.value
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// request_status: null/undefined/1 = no request yet, anything else = existing request
|
|
85
|
+
const hasExistingRequest = computed(() => {
|
|
86
|
+
const s = campaign.value?.request_status
|
|
87
|
+
return s !== null && s !== undefined && s !== 1
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const existingRequestStatus = computed(() => {
|
|
91
|
+
switch (campaign.value?.request_status) {
|
|
92
|
+
case 2: return $i18n.t("keys.campaigns.status_pending")
|
|
93
|
+
case 3: return $i18n.t("keys.campaigns.status_approved")
|
|
94
|
+
case 4: return $i18n.t("keys.campaigns.status_approved")
|
|
95
|
+
case 5: return $i18n.t("keys.campaigns.status_completed")
|
|
96
|
+
case 6: return $i18n.t("keys.campaigns.status_refused")
|
|
97
|
+
case 7: return $i18n.t("keys.campaigns.status_cancelled")
|
|
98
|
+
default: return ""
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
const isRefused = computed(() => campaign.value?.request_status === 6)
|
|
103
|
+
const refusedReason = computed(() => campaign.value?.request_admin_notes || "")
|
|
104
|
+
|
|
69
105
|
async function submit() {
|
|
70
106
|
if (!canSubmit.value) return
|
|
71
107
|
submitting.value = true
|
|
@@ -76,15 +112,27 @@ async function submit() {
|
|
|
76
112
|
platform_ids: [selectedPlatformId.value],
|
|
77
113
|
region_ids: [selectedRegionId.value],
|
|
78
114
|
description: description.value || "-",
|
|
79
|
-
quantity_keys: 1,
|
|
115
|
+
quantity_keys: Number(quantity.value) || 1,
|
|
80
116
|
})
|
|
81
117
|
success.value = true
|
|
82
118
|
setTimeout(() => {
|
|
83
119
|
navigateTo(`/${locale.value}/key-campaigns`)
|
|
84
120
|
}, 2000)
|
|
85
121
|
} catch (e: any) {
|
|
86
|
-
const
|
|
87
|
-
|
|
122
|
+
const status = e?.response?.status
|
|
123
|
+
const errorCode = e?.response?.data?.error_code
|
|
124
|
+
if (status === 409) {
|
|
125
|
+
requestError.value = $i18n.t("keys.campaigns.error_duplicate")
|
|
126
|
+
} else if (status === 403 && errorCode === "user_key_blocked") {
|
|
127
|
+
requestError.value = $i18n.t("keys.campaigns.error_user_blocked")
|
|
128
|
+
} else if (status === 403) {
|
|
129
|
+
requestError.value = $i18n.t("keys.campaigns.error_not_eligible")
|
|
130
|
+
} else if (status === 422 && errorCode === "pending_limit_reached") {
|
|
131
|
+
requestError.value = $i18n.t("keys.campaigns.error_pending_limit")
|
|
132
|
+
} else {
|
|
133
|
+
const msg = e?.response?.data?.message || e?.message || ""
|
|
134
|
+
requestError.value = msg || $i18n.t("keys.campaigns.error_request")
|
|
135
|
+
}
|
|
88
136
|
} finally {
|
|
89
137
|
submitting.value = false
|
|
90
138
|
}
|
|
@@ -126,50 +174,74 @@ function goBack() {
|
|
|
126
174
|
<p v-if="campaign?.name" class="campaign-name">{{ campaign.name }}</p>
|
|
127
175
|
</div>
|
|
128
176
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
<
|
|
132
|
-
|
|
133
|
-
<div class="
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
class="option"
|
|
139
|
-
:class="{ selected: selectedPlatformId === p.id }"
|
|
140
|
-
@click="selectedPlatformId = p.id"
|
|
141
|
-
>
|
|
142
|
-
{{ p.name }}
|
|
143
|
-
</button>
|
|
177
|
+
<!-- Already has a request -->
|
|
178
|
+
<div v-if="hasExistingRequest" class="existing-request-notice">
|
|
179
|
+
<MGIcon size="1x" icon="version" class="notice-icon" />
|
|
180
|
+
<div class="notice-texts">
|
|
181
|
+
<div class="notice-title">{{ $t("keys.campaigns.already_requested") }}</div>
|
|
182
|
+
<div class="notice-status">{{ existingRequestStatus }}</div>
|
|
183
|
+
<div v-if="isRefused && refusedReason" class="notice-reason">
|
|
184
|
+
<span class="notice-reason-label">{{ $t("keys.campaigns.refused_reason") }}</span>
|
|
185
|
+
<span class="notice-reason-text">{{ refusedReason }}</span>
|
|
144
186
|
</div>
|
|
145
187
|
</div>
|
|
188
|
+
<button class="btn notice-back" @click="goBack">
|
|
189
|
+
{{ $t("keys.campaigns.back_to_campaign") }}
|
|
190
|
+
</button>
|
|
191
|
+
</div>
|
|
146
192
|
|
|
147
|
-
|
|
148
|
-
<div class="
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
class="
|
|
156
|
-
:class="{ selected: selectedRegionId === r.id }"
|
|
157
|
-
@click="selectedRegionId = r.id"
|
|
158
|
-
>
|
|
159
|
-
{{ r.name }}
|
|
193
|
+
<form v-else class="form" @submit.prevent="submit">
|
|
194
|
+
<div class="required-data">
|
|
195
|
+
<div class="required-data-header" @click="toggleBox">
|
|
196
|
+
<div class="required-data-header-left">
|
|
197
|
+
<MGIcon size="1x" icon="check" :style="{ color: isBoxOpen ? 'var(--key-accent, var(--primary, #D297FF))' : 'var(--inactive)' }" />
|
|
198
|
+
<span>{{ $t("keys.campaigns.required_data") }}</span>
|
|
199
|
+
</div>
|
|
200
|
+
<button type="button" class="box-toggler" :aria-expanded="isBoxOpen">
|
|
201
|
+
<MGIcon icon="chevron-down" :class="{ rotate: isBoxOpen }" />
|
|
160
202
|
</button>
|
|
161
203
|
</div>
|
|
162
|
-
</div>
|
|
163
204
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
205
|
+
<div v-show="isBoxOpen" class="required-data-body">
|
|
206
|
+
<div class="form-row">
|
|
207
|
+
<label class="label">{{ $t("keys.campaigns.platform") }}</label>
|
|
208
|
+
<select v-model.number="selectedPlatformId" class="select">
|
|
209
|
+
<option :value="null" disabled>{{ $t("keys.campaigns.select_option") }}</option>
|
|
210
|
+
<option v-for="p in platforms" :key="p.id" :value="p.id">{{ p.name }}</option>
|
|
211
|
+
</select>
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
<div class="form-row">
|
|
215
|
+
<label class="label">{{ $t("keys.campaigns.region") }}</label>
|
|
216
|
+
<select v-model.number="selectedRegionId" class="select">
|
|
217
|
+
<option :value="null" disabled>{{ $t("keys.campaigns.select_option") }}</option>
|
|
218
|
+
<option v-for="r in regions" :key="r.id" :value="r.id">{{ r.name }}</option>
|
|
219
|
+
</select>
|
|
220
|
+
</div>
|
|
221
|
+
|
|
222
|
+
<div class="form-row" v-if="maxKeysForUser > 1">
|
|
223
|
+
<label class="label">{{ $t("keys.campaigns.quantity") }}</label>
|
|
224
|
+
<input
|
|
225
|
+
v-model.number="quantity"
|
|
226
|
+
type="number"
|
|
227
|
+
min="1"
|
|
228
|
+
:max="maxKeysForUser"
|
|
229
|
+
class="input quantity-input"
|
|
230
|
+
:placeholder="$t('keys.campaigns.quantity')"
|
|
231
|
+
@change="clampQuantity"
|
|
232
|
+
/>
|
|
233
|
+
</div>
|
|
234
|
+
|
|
235
|
+
<div class="form-row">
|
|
236
|
+
<label class="label">{{ $t("keys.campaigns.description_optional") }}</label>
|
|
237
|
+
<textarea
|
|
238
|
+
v-model="description"
|
|
239
|
+
class="textarea"
|
|
240
|
+
:placeholder="$t('keys.campaigns.description_placeholder')"
|
|
241
|
+
rows="3"
|
|
242
|
+
/>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
173
245
|
</div>
|
|
174
246
|
|
|
175
247
|
<div v-if="requestError" class="req-error">{{ requestError }}</div>
|
|
@@ -242,55 +314,120 @@ function goBack() {
|
|
|
242
314
|
|
|
243
315
|
.form { display: flex; flex-direction: column; gap: 24px; }
|
|
244
316
|
|
|
245
|
-
.
|
|
317
|
+
.required-data {
|
|
246
318
|
display: flex;
|
|
247
319
|
flex-direction: column;
|
|
248
|
-
|
|
320
|
+
background: var(--bg-app-badge);
|
|
321
|
+
border: 1px solid var(--button-secondary-default-bg);
|
|
249
322
|
}
|
|
250
323
|
|
|
251
|
-
.
|
|
252
|
-
|
|
324
|
+
.required-data-header {
|
|
325
|
+
display: flex;
|
|
326
|
+
align-items: center;
|
|
327
|
+
justify-content: space-between;
|
|
328
|
+
gap: 10px;
|
|
329
|
+
padding: 16px 20px;
|
|
330
|
+
font-size: 14px;
|
|
253
331
|
font-weight: 600;
|
|
254
332
|
color: var(--card-article-title);
|
|
333
|
+
border-bottom: 1px solid var(--button-secondary-default-bg);
|
|
334
|
+
cursor: pointer;
|
|
255
335
|
}
|
|
256
336
|
|
|
257
|
-
.
|
|
337
|
+
.required-data-header-left {
|
|
258
338
|
display: flex;
|
|
259
|
-
|
|
260
|
-
gap:
|
|
339
|
+
align-items: center;
|
|
340
|
+
gap: 10px;
|
|
261
341
|
}
|
|
262
342
|
|
|
263
|
-
.
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
font-weight: 500;
|
|
267
|
-
border: 1px solid var(--button-secondary-default-bg);
|
|
343
|
+
.box-toggler {
|
|
344
|
+
display: flex;
|
|
345
|
+
align-items: center;
|
|
268
346
|
background: transparent;
|
|
347
|
+
border: none;
|
|
269
348
|
color: var(--secondary-info-fg);
|
|
270
349
|
cursor: pointer;
|
|
271
|
-
transition: border-color 0.15s, color 0.15s;
|
|
272
350
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
border-color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
276
|
-
color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
277
|
-
background: var(--key-accent-subtle-bg, rgba(210, 151, 255, 0.08));
|
|
278
|
-
}
|
|
351
|
+
svg { transition: transform 0.15s; }
|
|
352
|
+
svg.rotate { transform: rotate(180deg); }
|
|
279
353
|
}
|
|
280
354
|
|
|
281
|
-
.
|
|
282
|
-
|
|
355
|
+
.existing-request-notice {
|
|
356
|
+
display: flex;
|
|
357
|
+
align-items: flex-start;
|
|
358
|
+
gap: 14px;
|
|
359
|
+
padding: 20px;
|
|
283
360
|
background: var(--bg-app-badge);
|
|
284
361
|
border: 1px solid var(--button-secondary-default-bg);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.notice-icon { color: var(--key-accent, var(--primary, #D297FF)); margin-top: 2px; }
|
|
365
|
+
|
|
366
|
+
.notice-texts { flex: 1; display: flex; flex-direction: column; gap: 4px; }
|
|
367
|
+
|
|
368
|
+
.notice-title { font-size: 14px; font-weight: 600; color: var(--card-article-title); }
|
|
369
|
+
.notice-status { font-size: 13px; color: var(--secondary-info-fg); }
|
|
370
|
+
|
|
371
|
+
.notice-reason {
|
|
372
|
+
display: flex;
|
|
373
|
+
flex-direction: column;
|
|
374
|
+
gap: 2px;
|
|
375
|
+
margin-top: 6px;
|
|
376
|
+
font-size: 13px;
|
|
377
|
+
|
|
378
|
+
.notice-reason-label { font-weight: 600; color: var(--card-article-title); }
|
|
379
|
+
.notice-reason-text { color: var(--secondary-info-fg); }
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.notice-back {
|
|
383
|
+
background: transparent;
|
|
384
|
+
border: 1px solid var(--button-secondary-default-bg);
|
|
385
|
+
color: var(--card-article-title);
|
|
386
|
+
padding: 8px 16px;
|
|
387
|
+
font-size: 13px;
|
|
388
|
+
font-weight: 600;
|
|
389
|
+
cursor: pointer;
|
|
390
|
+
white-space: nowrap;
|
|
391
|
+
&:hover { border-color: var(--key-accent, var(--primary, #D297FF)); }
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
.form-row {
|
|
395
|
+
display: flex;
|
|
396
|
+
flex-direction: column;
|
|
397
|
+
gap: 10px;
|
|
398
|
+
padding: 20px;
|
|
399
|
+
& + .form-row { border-top: 1px solid var(--button-secondary-default-bg); }
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.label {
|
|
403
|
+
font-size: 13px;
|
|
404
|
+
font-weight: 600;
|
|
405
|
+
color: var(--card-article-title);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.select, .input, .textarea {
|
|
409
|
+
width: 100%;
|
|
410
|
+
background: var(--body-bg-card, var(--bg-app-badge));
|
|
411
|
+
border: 1px solid var(--button-secondary-default-bg);
|
|
285
412
|
color: var(--card-article-title);
|
|
286
413
|
font-size: 13px;
|
|
287
414
|
padding: 10px 12px;
|
|
288
|
-
resize: vertical;
|
|
289
415
|
outline: none;
|
|
290
416
|
font-family: inherit;
|
|
291
417
|
&:focus { border-color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF)))); }
|
|
292
418
|
}
|
|
293
419
|
|
|
420
|
+
.select {
|
|
421
|
+
appearance: auto;
|
|
422
|
+
cursor: pointer;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.textarea { resize: vertical; }
|
|
426
|
+
|
|
427
|
+
.quantity-input {
|
|
428
|
+
width: 120px;
|
|
429
|
+
}
|
|
430
|
+
|
|
294
431
|
.req-error {
|
|
295
432
|
font-size: 13px;
|
|
296
433
|
color: var(--danger, #e53935);
|
|
@@ -303,7 +440,7 @@ function goBack() {
|
|
|
303
440
|
font-size: 14px;
|
|
304
441
|
font-weight: 700;
|
|
305
442
|
background: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
306
|
-
color: #
|
|
443
|
+
color: var(--key-accent-ink, #13161C);
|
|
307
444
|
border: none;
|
|
308
445
|
cursor: pointer;
|
|
309
446
|
transition: opacity 0.15s;
|