diff --git a/apps/admin/vite.config.ts b/apps/admin/vite.config.ts
index 5520ea0..3118525 100644
--- a/apps/admin/vite.config.ts
+++ b/apps/admin/vite.config.ts
@@ -1,6 +1,7 @@
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
+import { resolveApiDevTarget } from '../../scripts/dev-api-target.mjs';
import { visualizer } from 'rollup-plugin-visualizer';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
@@ -8,6 +9,7 @@ import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
export default defineConfig(({ mode }) => {
const analyze = process.env.ANALYZE === '1' || mode === 'analyze';
+ const apiTarget = resolveApiDevTarget();
return {
plugins: [
@@ -75,8 +77,8 @@ export default defineConfig(({ mode }) => {
server: {
port: 5174,
proxy: {
- '/api': { target: 'http://localhost:3000', changeOrigin: true },
- '/uploads': { target: 'http://localhost:3000', changeOrigin: true },
+ '/api': { target: apiTarget, changeOrigin: true },
+ '/uploads': { target: apiTarget, changeOrigin: true },
},
},
};
diff --git a/apps/player/src/i18n/en-US.ts b/apps/player/src/i18n/en-US.ts
index 5dd5d6e..3c6602b 100644
--- a/apps/player/src/i18n/en-US.ts
+++ b/apps/player/src/i18n/en-US.ts
@@ -476,6 +476,7 @@ export default {
place_failed: 'Bet failed',
},
profile: {
+ settings: 'Settings',
edit: 'Edit Profile',
language: 'Language',
avatar: 'Avatar',
diff --git a/apps/player/src/i18n/ms-MY.ts b/apps/player/src/i18n/ms-MY.ts
index b57d83e..38bf540 100644
--- a/apps/player/src/i18n/ms-MY.ts
+++ b/apps/player/src/i18n/ms-MY.ts
@@ -482,6 +482,7 @@ export default {
place_failed: 'Pertaruhan gagal',
},
profile: {
+ settings: 'Tetapan',
edit: 'Edit Profil',
language: 'Bahasa',
avatar: 'Avatar',
diff --git a/apps/player/src/i18n/zh-CN.ts b/apps/player/src/i18n/zh-CN.ts
index 9b9f51d..b8a0752 100644
--- a/apps/player/src/i18n/zh-CN.ts
+++ b/apps/player/src/i18n/zh-CN.ts
@@ -476,6 +476,7 @@ export default {
place_failed: '下注失败',
},
profile: {
+ settings: '设置',
edit: '修改资料',
language: '语言',
avatar: '选择头像',
diff --git a/apps/player/src/views/ForgotPasswordView.vue b/apps/player/src/views/ForgotPasswordView.vue
index 8d335b7..57c1350 100644
--- a/apps/player/src/views/ForgotPasswordView.vue
+++ b/apps/player/src/views/ForgotPasswordView.vue
@@ -102,7 +102,8 @@ function goLogin() {
-
+
@@ -214,7 +218,7 @@ const fieldError = () => {
position: absolute;
top: max(12px, env(safe-area-inset-top));
right: 16px;
- z-index: 2;
+ z-index: 10;
}
.login-page {
@@ -226,7 +230,7 @@ const fieldError = () => {
flex-direction: column;
align-items: center;
justify-content: flex-end;
- padding: 30vh 16px calc(10vh + max(20px, env(safe-area-inset-bottom)));
+ padding: 30vh 16px max(20px, env(safe-area-inset-bottom));
background-color: var(--bg-body);
background-size: cover;
background-position: center top;
@@ -247,21 +251,33 @@ const fieldError = () => {
z-index: 0;
}
-.login-page > * {
+.login-stack {
position: relative;
z-index: 1;
-}
-
-.login-form {
- position: relative;
width: 100%;
max-width: 320px;
display: flex;
flex-direction: column;
gap: 8px;
+}
+
+.login-form {
+ position: relative;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
padding: 14px;
}
+.login-actions {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 2px;
+ padding: 0 14px 4px;
+}
+
.login-form.is-busy {
pointer-events: none;
}
@@ -403,14 +419,14 @@ label {
}
.btn-skip {
- margin-top: 2px;
- padding: 8px 14px;
+ padding: 6px 14px;
border: none;
background: transparent;
color: rgba(255, 255, 255, 0.55);
font-size: 13px;
font-weight: 600;
cursor: pointer;
+ text-align: center;
}
.btn-skip:active {
@@ -418,11 +434,7 @@ label {
}
.btn-skip-light {
- position: absolute;
- bottom: calc(20px + env(safe-area-inset-bottom));
- left: 50%;
- transform: translateX(-50%);
- padding: 8px 16px;
+ padding: 6px 16px;
border: none;
background: transparent;
color: rgba(255, 255, 255, 0.45);
@@ -430,6 +442,7 @@ label {
font-weight: 300;
cursor: pointer;
white-space: nowrap;
+ text-align: center;
}
.btn-skip-light:active {
diff --git a/apps/player/vite.config.ts b/apps/player/vite.config.ts
index bf00cfa..1704b59 100644
--- a/apps/player/vite.config.ts
+++ b/apps/player/vite.config.ts
@@ -1,6 +1,9 @@
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
+import { resolveApiDevTarget } from '../../scripts/dev-api-target.mjs';
+
+const apiTarget = resolveApiDevTarget();
export default defineConfig({
plugins: [vue()],
@@ -37,8 +40,8 @@ export default defineConfig({
server: {
port: 5173,
proxy: {
- '/api': { target: 'http://localhost:3000', changeOrigin: true },
- '/uploads': { target: 'http://localhost:3000', changeOrigin: true },
+ '/api': { target: apiTarget, changeOrigin: true },
+ '/uploads': { target: apiTarget, changeOrigin: true },
},
},
});
diff --git a/scripts/dev-api-target.mjs b/scripts/dev-api-target.mjs
new file mode 100644
index 0000000..e914b0c
--- /dev/null
+++ b/scripts/dev-api-target.mjs
@@ -0,0 +1,19 @@
+import { existsSync, readFileSync } from 'node:fs';
+import { dirname, resolve } from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
+
+/** 本地 dev:与 apps/api/.env 的 PORT 对齐,供 player/admin Vite 代理使用 */
+export function resolveApiDevTarget() {
+ if (process.env.VITE_DEV_API_TARGET) return process.env.VITE_DEV_API_TARGET;
+ if (process.env.API_DEV_TARGET) return process.env.API_DEV_TARGET;
+
+ let port = '3000';
+ const envPath = resolve(repoRoot, 'apps/api/.env');
+ if (existsSync(envPath)) {
+ const match = readFileSync(envPath, 'utf8').match(/^PORT=(\d+)\s*$/m);
+ if (match) port = match[1];
+ }
+ return `http://localhost:${port}`;
+}