feat: refactor agent manager, media library, and player UX
- Split admin users page into player/tier-1/tier-2 tabs with affiliation labels and context-specific create dialogs - Add media library with uploaded_files migration, list/delete unused files API, and admin nav route - Enforce player username format (alphanumeric 3-32) on frontend and backend via shared package - Improve admin dialog/panel styling; refine player parlay and match bet card kickoff display Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -747,7 +747,8 @@ function statusTagType(s: string) {
|
||||
/>
|
||||
<el-form label-width="100px" class="create-form">
|
||||
<el-form-item :label="t('user.col.username')" required>
|
||||
<el-input v-model="createForm.username" :placeholder="t('agent_portal.username_ph')" />
|
||||
<el-input v-model="createForm.username" :placeholder="t('user.ph.username_player')" />
|
||||
<div class="field-hint">{{ t('user.hint.username_player') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('user.field.password')" required>
|
||||
<el-input v-model="createForm.password" type="text" autocomplete="off" />
|
||||
@@ -783,7 +784,8 @@ function statusTagType(s: string) {
|
||||
<el-tag :type="statusTagType(editForm.status)" size="small">{{ statusLabel(editForm.status) }}</el-tag>
|
||||
</div>
|
||||
<el-form-item :label="t('user.col.username')">
|
||||
<el-input v-model="editForm.username" :placeholder="t('user.ph.username_unique')" />
|
||||
<el-input v-model="editForm.username" :placeholder="t('user.ph.username_player')" />
|
||||
<div class="field-hint">{{ t('user.hint.username_player') }}</div>
|
||||
</el-form-item>
|
||||
<div class="password-mgmt-block">
|
||||
<div class="block-title">{{ t('user.section.password_mgmt') }}</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { FormValidationError } from '../../i18n/form-validation';
|
||||
import { assertPlayerUsername } from '../user-form';
|
||||
|
||||
export interface AgentPlayerCreateForm {
|
||||
username: string;
|
||||
@@ -65,7 +66,7 @@ export function emptyAgentPlayerCreateForm(): AgentPlayerCreateForm {
|
||||
}
|
||||
|
||||
export function buildAgentCreatePlayerPayload(form: AgentPlayerCreateForm) {
|
||||
if (!form.username.trim()) throw new FormValidationError('err.username_required');
|
||||
assertPlayerUsername(form.username);
|
||||
if (form.password.length < 8) throw new FormValidationError('err.password_min');
|
||||
if (form.password !== form.confirmPassword) throw new FormValidationError('err.password_mismatch');
|
||||
if (form.initialDeposit < 0) throw new FormValidationError('err.amount_negative');
|
||||
@@ -119,7 +120,7 @@ export function editFormFromAgentDetail(d: AgentPlayerDetail): AgentPlayerEditFo
|
||||
}
|
||||
|
||||
export function buildAgentUpdatePlayerPayload(form: AgentPlayerEditForm) {
|
||||
if (!form.username.trim()) throw new FormValidationError('err.username_required');
|
||||
assertPlayerUsername(form.username);
|
||||
if (form.newPassword && form.newPassword.length < 8) {
|
||||
throw new FormValidationError('err.password_min');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user