@kennofizet/rewardplay-frontend 1.0.5 → 1.0.7

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/README.md CHANGED
@@ -1,38 +1,38 @@
1
- # @kennofizet/rewardplay-frontend
1
+ # RewardPlay Frontend
2
2
 
3
- Vue 3 frontend package for **RewardPlay**: game UI (bag, shop, daily reward, ranking, settings) that talks to the RewardPlay backend API.
3
+ Vue 3 UI for **RewardPlay**: login, bag, shop, daily rewards, ranking, and settings. It talks to two APIs — **Core** (zones, auth check) and **RewardPlay** (game data) — so you pass **coreUrl**, **backendUrl**, and **token** when mounting.
4
4
 
5
- ## What This Package Is
5
+ ---
6
6
 
7
- - **Vue 3 component library** for the RewardPlay game interface (login, loading, bag/gear, shop, daily rewards, ranking, manage settings).
8
- - **Token-based**: you pass a backend URL and token; the package uses them for all API calls.
9
- - **Embeddable**: mount it in a host app inside a div (e.g. after login or when entering the game section).
10
- - Backend API, auth, and data format are defined in **@kennofizet/rewardplay-backend**. Use that package (or its docs) for token, endpoints, and data structures.
11
-
12
- ## Installation
7
+ ## Install
13
8
 
14
9
  ```bash
15
10
  npm i @kennofizet/rewardplay-frontend
16
11
  ```
17
12
 
18
- **Peer dependency:** Vue 3 (`vue@^3.2.0`). The host project must provide Vue.
13
+ **Peer dependency:** Vue 3 (`vue@^3.2.0`). Your app must provide Vue.
19
14
 
20
- ## Setup: Mount Point and Initialization
15
+ ---
21
16
 
22
- ### 1. Mount point in template
17
+ ## Mount in 3 steps
23
18
 
24
- Render a stable DOM node only when you are ready to mount RewardPlay (e.g. after you have a token):
19
+ ### 1. Add a mount point (only when you have a token)
25
20
 
26
21
  ```html
27
22
  <div v-show="initialized" id="rewardplay-mount-point"></div>
28
23
  ```
29
24
 
30
- - Use `v-show="initialized"` (or `v-if`) so the element exists only when `initialized` is true, then mount in a `nextTick` after setting `initialized = true`.
31
- - The ID (`rewardplay-mount-point`) is what you pass to `document.getElementById` before mounting.
25
+ Show it only when `initialized` is true (e.g. after login), then mount in a `nextTick` after setting `initialized = true`. Use the same ID in `document.getElementById` below.
26
+
27
+ ### 2. Get token and URLs
28
+
29
+ Your app must provide:
32
30
 
33
- ### 2. Initialize and mount in your app
31
+ - **coreUrl** Base URL of the Core API (e.g. `https://your-app.com/api/knf`). Used for auth check, zones, managed zones.
32
+ - **backendUrl** — Base URL of the RewardPlay API (e.g. `https://your-app.com/api/knf/rewardplay`). Used for user data, bag, shop, daily rewards, ranking, manifest, settings.
33
+ - **token** — RewardPlay token (from your backend; see rewardplay-backend README).
34
34
 
35
- Example (Vue 3 Composition API with `createApp`):
35
+ ### 3. Create app and use the plugin
36
36
 
37
37
  ```js
38
38
  import { createApp, ref, nextTick } from 'vue'
@@ -41,15 +41,13 @@ import RewardPlay, { RewardPlayPage } from '@kennofizet/rewardplay-frontend'
41
41
  const initialized = ref(false)
42
42
  let rewardPlayApp = null
43
43
 
44
- async function initialize() {
45
- const backendUrl = 'https://your-backend.com' // from your config
46
- if (!backendUrl?.trim()) {
47
- // handle error
48
- return
49
- }
44
+ async function initRewardPlay() {
45
+ const coreUrl = 'https://your-app.com/api/knf' // from your config
46
+ const backendUrl = 'https://your-app.com/api/knf/rewardplay' // from your config
47
+ if (!coreUrl?.trim() || !backendUrl?.trim()) return
50
48
 
51
49
  try {
52
- const token = await fetchToken() // get token from your backend (see rewardplay-backend)
50
+ const token = await fetchYourRewardPlayToken() // your API
53
51
  initialized.value = true
54
52
  await nextTick()
55
53
 
@@ -66,10 +64,10 @@ async function initialize() {
66
64
  fontUrls: [],
67
65
  backgroundImage: null,
68
66
  language: 'vi', // 'en' | 'vi'
69
- // enableUnzip: true, // if your RewardPlayPage supports it
70
67
  })
71
68
 
72
69
  rewardPlayApp.use(RewardPlay, {
70
+ coreUrl: coreUrl.trim(),
73
71
  backendUrl: backendUrl.trim(),
74
72
  token,
75
73
  })
@@ -77,72 +75,76 @@ async function initialize() {
77
75
  rewardPlayApp.mount(mountPoint)
78
76
  } catch (err) {
79
77
  initialized.value = false
80
- // handle err
78
+ // handle error
81
79
  }
82
80
  }
83
81
 
84
- // e.g. in onMounted or after login
82
+ // e.g. onMounted or after login
85
83
  onMounted(() => {
86
- initialize()
84
+ initRewardPlay()
87
85
  })
88
86
  ```
89
87
 
90
- ### 3. Plugin options (required)
88
+ ---
89
+
90
+ ## Plugin options (all required)
91
+
92
+ | Option | Type | Description |
93
+ |--------|------|-------------|
94
+ | `coreUrl` | string | Base URL of Core API (zones, auth check). |
95
+ | `backendUrl` | string | Base URL of RewardPlay API (game data, manifest). |
96
+ | `token` | string | RewardPlay auth token. |
91
97
 
92
- | Option | Type | Description |
93
- |------------|--------|--------------------------------|
94
- | `backendUrl` | string | Base URL of RewardPlay API |
95
- | `token` | string | RewardPlay auth token |
98
+ All three are required: `app.use(RewardPlay, { coreUrl, backendUrl, token })`.
96
99
 
97
- Both are required when calling `app.use(RewardPlay, { backendUrl, token })`.
100
+ ---
98
101
 
99
- ### 4. Vite: optimizeDeps
102
+ ## Vite: same Vue instance
100
103
 
101
- If you mount RewardPlay in a separate app with `createApp(RewardPlayPage).use(RewardPlay, { backendUrl, token }).mount(...)`, add the package to Vite’s `optimizeDeps.include` so it uses the same Vue instance and `inject('gameApi')` works:
104
+ If you mount RewardPlay in a separate `createApp(RewardPlayPage)`, add the package to Vite so it shares the same Vue instance and `inject('gameApi')` works:
102
105
 
103
106
  ```js
104
- // vite.config.js (or vite.config.ts)
107
+ // vite.config.js
105
108
  export default {
106
- // ...
107
109
  optimizeDeps: {
108
110
  include: ['@kennofizet/rewardplay-frontend'],
109
- // ... rest of your config
110
111
  },
111
112
  }
112
113
  ```
113
114
 
114
- Without this, dev and build can end up with a different Vue instance for the package and `gameApi` may be missing (e.g. “gameApi.... is not a function”)
115
+ ---
116
+
117
+ ## RewardPlayPage props (optional)
118
+
119
+ | Prop | Type | Default | Description |
120
+ |------|------|--------|-------------|
121
+ | `imageUrls` | Array | `[]` | URLs for image manifest/assets |
122
+ | `scriptUrls` | Array | `[]` | Script URLs to load |
123
+ | `stylesheetUrls` | Array | `[]` | CSS URLs |
124
+ | `fontUrls` | Array | `[]` | Font URLs |
125
+ | `backgroundImage` | string | null | Background image URL |
126
+ | `language` | string | `'en'` | `'en'` or `'vi'` |
127
+ | `rotate` | boolean | true | Auto-rotate in portrait |
128
+ | `customStyles` | Object | `{}` | Extra CSS variables |
115
129
 
116
- ### 5. RewardPlayPage root props (optional)
130
+ ---
117
131
 
118
- | Prop | Type | Default | Description |
119
- |------------------|--------|--------|--------------------------------|
120
- | `imageUrls` | Array | `[]` | URLs for image manifest/assets |
121
- | `scriptUrls` | Array | `[]` | Script URLs to load |
122
- | `stylesheetUrls` | Array | `[]` | CSS URLs |
123
- | `fontUrls` | Array | `[]` | Font URLs |
124
- | `backgroundImage`| string | null | Background image URL |
125
- | `language` | string | `'en'` | UI language: `'en'` or `'vi'` |
126
- | `rotate` | boolean| true | Auto-rotate in portrait |
127
- | `customStyles` | Object | `{}` | Extra inline/CSS variables |
132
+ ## Backend and token
128
133
 
129
- ## Backend and data
134
+ - **Token:** Your host app gets the RewardPlay token from your backend (see **kennofizet/rewardplay-backend** README).
135
+ - **URLs:** Core and RewardPlay can live on the same app; just pass the correct base paths for `coreUrl` and `backendUrl`.
130
136
 
131
- - **Token**: Your host app must obtain the RewardPlay token (e.g. from your own backend that talks to RewardPlay). How to issue/validate the token and which endpoints to call is defined in **@kennofizet/rewardplay-backend**.
132
- - **API**: The frontend calls endpoints under `backendUrl` (e.g. `/api/rewardplay/auth/user-data`, `/api/rewardplay/player/shop`, etc.). Base URL, routes, and response shapes are documented in the backend package.
133
- - For API contracts, env vars, and server setup, read **@kennofizet/rewardplay-backend** (or the backend README in the same repo).
137
+ ---
134
138
 
135
139
  ## Exports
136
140
 
137
- - **default**: plugin object `{ install }` use with `app.use(RewardPlay, { backendUrl, token })`.
138
- - **RewardPlayPage**: root Vue component to mount.
139
- - **installGameModule**, **createGameApi**, **RewardPlayPage**, **ComingSoonPage**, **LoadingSource**, **LoginScreen**.
140
- - Utilities: **ResourceLoader**, **useResourceLoader**, constants helpers, **createTranslator**, **translations**.
141
+ - **default**Plugin: `app.use(RewardPlay, { coreUrl, backendUrl, token })`
142
+ - **RewardPlayPage** Root component to mount
143
+ - **createGameApi**, **installGameModule**, **ComingSoonPage**, **LoadingSource**, **LoginScreen**
144
+ - **ResourceLoader**, **useResourceLoader**, constants helpers, **createTranslator**, **translations**
141
145
 
142
- ## Development
146
+ ---
143
147
 
144
- If you work inside the repo (e.g. `rewardplay-packages`):
148
+ ## Development (editing the package)
145
149
 
146
- - Dependencies are usually installed at the **root** of the repo: `npm install` at root.
147
- - The package entry is `src/index.js`; the host can resolve source directly (no build step required for development).
148
- - For a production build of the frontend package, run `npm run production` in this package (output in `dist/`).
150
+ From the **rewardplay-packages** repo root: `npm install`, then `npm run dev:frontend` or `npm run build:frontend`. Package entry is `src/index.js`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kennofizet/rewardplay-frontend",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "RewardPlay frontend package - Token-based API client for RewardPlay",
5
5
  "main": "./src/index.js",
6
6
  "module": "./src/index.js",
@@ -49,4 +49,4 @@
49
49
  "engines": {
50
50
  "node": ">=16.0.0"
51
51
  }
52
- }
52
+ }
package/src/api/index.js CHANGED
@@ -2,11 +2,16 @@ import axios from 'axios'
2
2
 
3
3
  /**
4
4
  * Create game API client
5
+ * @param {string} coreUrl - Base URL for core API
5
6
  * @param {string} backendUrl - Base URL for backend API
6
7
  * @param {string} token - RewardPlay token (required)
7
8
  * @returns {Object} API client with methods
8
9
  */
9
- export function createGameApi(backendUrl, token) {
10
+ export function createGameApi(coreUrl, backendUrl, token) {
11
+ if (!coreUrl) {
12
+ throw new Error('Core URL is required')
13
+ }
14
+
10
15
  if (!backendUrl) {
11
16
  throw new Error('Backend URL is required')
12
17
  }
@@ -16,11 +21,11 @@ export function createGameApi(backendUrl, token) {
16
21
  }
17
22
 
18
23
  const api = axios.create({
19
- baseURL: backendUrl,
24
+ // baseURL: backendUrl,
20
25
  headers: {
21
26
  'Content-Type': 'application/json',
22
27
  'Accept': 'application/json',
23
- 'X-RewardPlay-Token': token,
28
+ 'X-Knf-Token': token,
24
29
  },
25
30
  })
26
31
 
@@ -31,10 +36,10 @@ export function createGameApi(backendUrl, token) {
31
36
  if (selectedZone) {
32
37
  const zone = JSON.parse(selectedZone)
33
38
  if (zone && zone.id) {
34
- // Add zone_id to headers (similar to X-RewardPlay-Token)
39
+ // Add zone_id to headers (similar to X-Knf-Token)
35
40
  config.headers = config.headers || {}
36
- if (!config.headers['X-RewardPlay-Zone-Id']) {
37
- config.headers['X-RewardPlay-Zone-Id'] = zone.id.toString()
41
+ if (!config.headers['X-Knf-Zone-Id']) {
42
+ config.headers['X-Knf-Zone-Id'] = zone.id.toString()
38
43
  }
39
44
  }
40
45
  }
@@ -51,123 +56,125 @@ export function createGameApi(backendUrl, token) {
51
56
 
52
57
  return {
53
58
  // Auth
54
- checkUser: () => api.get('/api/rewardplay/auth/check'),
55
- getUserData: () => api.get('/api/rewardplay/auth/user-data'),
59
+ checkUser: () => api.get(coreUrl + '/auth/check'),
56
60
  // Zones the current user belongs to
57
- getZones: () => api.get('/api/rewardplay/player/zones'),
58
- getCustomImages: (params) => api.get('/api/rewardplay/player/custom-images', { params }),
59
- // Manifest
60
- getManifest: () => api.get('/api/rewardplay/manifest'),
61
- // Ranking (period: day | week | month | year)
62
- getRanking: (period = 'day') => api.get('/api/rewardplay/ranking', { params: { period } }),
61
+ getZones: () => api.get(coreUrl + '/player/zones'),
63
62
  // Zones the current user can manage (for settings)
64
- getManagedZones: () => api.get('/api/rewardplay/player/managed-zones'),
63
+ getManagedZones: () => api.get(coreUrl + '/player/managed-zones'),
65
64
  // Zone management (settings)
66
- getAllZones: (params) => api.get('/api/rewardplay/zones', { params }),
67
- createZone: (data) => api.post('/api/rewardplay/zones', data),
68
- updateZone: (id, data) => api.put(`/api/rewardplay/zones/${id}`, data),
69
- deleteZone: (id) => api.delete(`/api/rewardplay/zones/${id}`),
65
+ getAllZones: (params) => api.get(coreUrl + '/zones', { params }),
66
+ createZone: (data) => api.post(coreUrl + '/zones', data),
67
+ updateZone: (id, data) => api.put(coreUrl + `/zones/${id}`, data),
68
+ deleteZone: (id) => api.delete(coreUrl + `/zones/${id}`),
70
69
  // Zone users (server members + assigned)
71
- getZoneUsers: (zoneId, params) => api.get(`/api/rewardplay/zones/${zoneId}/users`, { params }),
72
- assignZoneUser: (zoneId, userId) => api.post(`/api/rewardplay/zones/${zoneId}/users`, { user_id: userId }),
73
- removeZoneUser: (zoneId, userId) => api.delete(`/api/rewardplay/zones/${zoneId}/users/${userId}`),
70
+ getZoneUsers: (zoneId, params) => api.get(coreUrl + `/zones/${zoneId}/users`, { params }),
71
+ assignZoneUser: (zoneId, userId) => api.post(coreUrl + `/zones/${zoneId}/users`, { user_id: userId }),
72
+ removeZoneUser: (zoneId, userId) => api.delete(coreUrl + `/zones/${zoneId}/users/${userId}`),
74
73
 
74
+ // Player: custom images
75
+ getCustomImages: (params) => api.get(backendUrl + '/player/custom-images', { params }),
76
+ // Manifest
77
+ getManifest: () => api.get(backendUrl + '/manifest'),
78
+ // Ranking (period: day | week | month | year)
79
+ getRanking: (period = 'day') => api.get(backendUrl + '/ranking', { params: { period } }),
80
+ // RewardPlay: user data
81
+ getUserData: () => api.get(backendUrl + '/auth/user-data'),
75
82
  // Setting Items CRUD
76
- getSettingItems: (params) => api.get('/api/rewardplay/setting-items', { params }),
77
- suggestSettingItems: () => api.post('/api/rewardplay/setting-items/suggest'),
78
- createSettingItem: (data) => api.post('/api/rewardplay/setting-items', data),
83
+ getSettingItems: (params) => api.get(backendUrl + '/setting-items', { params }),
84
+ suggestSettingItems: () => api.post(backendUrl + '/setting-items/suggest'),
85
+ createSettingItem: (data) => api.post(backendUrl + '/setting-items', data),
79
86
  updateSettingItem: (id, data) => {
80
87
  if (data instanceof FormData) {
81
88
  if (!data.has('_method')) data.append('_method', 'PUT')
82
- return api.post(`/api/rewardplay/setting-items/${id}`, data)
89
+ return api.post(backendUrl + `/setting-items/${id}`, data)
83
90
  }
84
- return api.put(`/api/rewardplay/setting-items/${id}`, data)
91
+ return api.put(backendUrl + `/setting-items/${id}`, data)
85
92
  },
86
- deleteSettingItem: (id) => api.delete(`/api/rewardplay/setting-items/${id}`),
93
+ deleteSettingItem: (id) => api.delete(backendUrl + `/setting-items/${id}`),
87
94
 
88
95
  // Setting Options CRUD
89
- getSettingOptions: (params) => api.get('/api/rewardplay/setting-options', { params }),
90
- getSettingOption: (id) => api.get(`/api/rewardplay/setting-options/${id}`),
91
- createSettingOption: (data) => api.post('/api/rewardplay/setting-options', data),
92
- updateSettingOption: (id, data) => api.put(`/api/rewardplay/setting-options/${id}`, data),
93
- deleteSettingOption: (id) => api.delete(`/api/rewardplay/setting-options/${id}`),
96
+ getSettingOptions: (params) => api.get(backendUrl + '/setting-options', { params }),
97
+ getSettingOption: (id) => api.get(backendUrl + `/setting-options/${id}`),
98
+ createSettingOption: (data) => api.post(backendUrl + '/setting-options', data),
99
+ updateSettingOption: (id, data) => api.put(backendUrl + `/setting-options/${id}`, data),
100
+ deleteSettingOption: (id) => api.delete(backendUrl + `/setting-options/${id}`),
94
101
 
95
102
  // Setting Stats Transforms CRUD
96
- getSettingStatsTransforms: (params) => api.get('/api/rewardplay/setting-stats-transforms', { params }),
97
- createSettingStatsTransform: (data) => api.post('/api/rewardplay/setting-stats-transforms', data),
98
- updateSettingStatsTransform: (id, data) => api.put(`/api/rewardplay/setting-stats-transforms/${id}`, data),
99
- deleteSettingStatsTransform: (id) => api.delete(`/api/rewardplay/setting-stats-transforms/${id}`),
100
- suggestSettingStatsTransforms: () => api.post('/api/rewardplay/setting-stats-transforms/suggest'),
101
- getSettingStatsTransformsAllowedKeys: () => api.get('/api/rewardplay/setting-stats-transforms/allowed-keys'),
103
+ getSettingStatsTransforms: (params) => api.get(backendUrl + '/setting-stats-transforms', { params }),
104
+ createSettingStatsTransform: (data) => api.post(backendUrl + '/setting-stats-transforms', data),
105
+ updateSettingStatsTransform: (id, data) => api.put(backendUrl + `/setting-stats-transforms/${id}`, data),
106
+ deleteSettingStatsTransform: (id) => api.delete(backendUrl + `/setting-stats-transforms/${id}`),
107
+ suggestSettingStatsTransforms: () => api.post(backendUrl + '/setting-stats-transforms/suggest'),
108
+ getSettingStatsTransformsAllowedKeys: () => api.get(backendUrl + '/setting-stats-transforms/allowed-keys'),
102
109
 
103
110
  // Global data (accessible to both player and manage)
104
- getAllStats: () => api.get('/api/rewardplay/stats/all'),
105
- getRewardTypes: (mode) => api.get('/api/rewardplay/stats/reward-types', { params: { mode } }),
111
+ getAllStats: () => api.get(backendUrl + '/stats/all'),
112
+ getRewardTypes: (mode) => api.get(backendUrl + '/stats/reward-types', { params: { mode } }),
106
113
 
107
114
  // Setting Item Sets CRUD
108
- getSettingItemSets: (params) => api.get('/api/rewardplay/setting-item-sets', { params }),
109
- getItemsForZone: (params) => api.get('/api/rewardplay/setting-items/items-for-zone', { params }),
110
- createSettingItemSet: (data) => api.post('/api/rewardplay/setting-item-sets', data),
111
- updateSettingItemSet: (id, data) => api.put(`/api/rewardplay/setting-item-sets/${id}`, data),
112
- deleteSettingItemSet: (id) => api.delete(`/api/rewardplay/setting-item-sets/${id}`),
115
+ getSettingItemSets: (params) => api.get(backendUrl + '/setting-item-sets', { params }),
116
+ getItemsForZone: (params) => api.get(backendUrl + '/setting-items/items-for-zone', { params }),
117
+ createSettingItemSet: (data) => api.post(backendUrl + '/setting-item-sets', data),
118
+ updateSettingItemSet: (id, data) => api.put(backendUrl + `/setting-item-sets/${id}`, data),
119
+ deleteSettingItemSet: (id) => api.delete(backendUrl + `/setting-item-sets/${id}`),
113
120
 
114
121
  // Setting Stack Bonuses CRUD
115
- getStackBonuses: (params) => api.get('/api/rewardplay/setting-stack-bonuses', { params }),
116
- getStackBonus: (id) => api.get(`/api/rewardplay/setting-stack-bonuses/${id}`),
117
- createStackBonus: (data) => api.post('/api/rewardplay/setting-stack-bonuses', data),
118
- updateStackBonus: (id, data) => api.put(`/api/rewardplay/setting-stack-bonuses/${id}`, data),
119
- deleteStackBonus: (id) => api.delete(`/api/rewardplay/setting-stack-bonuses/${id}`),
120
- suggestStackBonuses: () => api.post('/api/rewardplay/setting-stack-bonuses/suggest'),
122
+ getStackBonuses: (params) => api.get(backendUrl + '/setting-stack-bonuses', { params }),
123
+ getStackBonus: (id) => api.get(backendUrl + `/setting-stack-bonuses/${id}`),
124
+ createStackBonus: (data) => api.post(backendUrl + '/setting-stack-bonuses', data),
125
+ updateStackBonus: (id, data) => api.put(backendUrl + `/setting-stack-bonuses/${id}`, data),
126
+ deleteStackBonus: (id) => api.delete(backendUrl + `/setting-stack-bonuses/${id}`),
127
+ suggestStackBonuses: () => api.post(backendUrl + '/setting-stack-bonuses/suggest'),
121
128
 
122
129
  // Setting Daily Rewards (Manage)
123
- getDailyRewardConfigs: (params) => api.get('/api/rewardplay/setting-daily-rewards', { params }), // Expects month/year
124
- saveDailyRewardConfig: (data) => api.post('/api/rewardplay/setting-daily-rewards', data), // Update or Create based on date
125
- suggestDailyRewards: (data) => api.post('/api/rewardplay/setting-daily-rewards/suggest', data),
130
+ getDailyRewardConfigs: (params) => api.get(backendUrl + '/setting-daily-rewards', { params }), // Expects month/year
131
+ saveDailyRewardConfig: (data) => api.post(backendUrl + '/setting-daily-rewards', data), // Update or Create based on date
132
+ suggestDailyRewards: (data) => api.post(backendUrl + '/setting-daily-rewards/suggest', data),
126
133
 
127
134
  // Setting Level Exps (Manage)
128
- getLevelExps: (params) => api.get('/api/rewardplay/setting-level-exps', { params }),
129
- getLevelExp: (id) => api.get(`/api/rewardplay/setting-level-exps/${id}`),
130
- createLevelExp: (data) => api.post('/api/rewardplay/setting-level-exps', data),
131
- updateLevelExp: (id, data) => api.put(`/api/rewardplay/setting-level-exps/${id}`, data),
132
- deleteLevelExp: (id) => api.delete(`/api/rewardplay/setting-level-exps/${id}`),
133
- suggestLevelExps: () => api.post('/api/rewardplay/setting-level-exps/suggest'),
135
+ getLevelExps: (params) => api.get(backendUrl + '/setting-level-exps', { params }),
136
+ getLevelExp: (id) => api.get(backendUrl + `/setting-level-exps/${id}`),
137
+ createLevelExp: (data) => api.post(backendUrl + '/setting-level-exps', data),
138
+ updateLevelExp: (id, data) => api.put(backendUrl + `/setting-level-exps/${id}`, data),
139
+ deleteLevelExp: (id) => api.delete(backendUrl + `/setting-level-exps/${id}`),
140
+ suggestLevelExps: () => api.post(backendUrl + '/setting-level-exps/suggest'),
134
141
 
135
142
  // Setting Events (Manage)
136
- getSettingEvents: (params) => api.get('/api/rewardplay/setting-events', { params }),
137
- getSettingEvent: (id) => api.get(`/api/rewardplay/setting-events/${id}`),
138
- suggestSettingEvents: () => api.post('/api/rewardplay/setting-events/suggest'),
139
- createSettingEvent: (data) => api.post('/api/rewardplay/setting-events', data),
143
+ getSettingEvents: (params) => api.get(backendUrl + '/setting-events', { params }),
144
+ getSettingEvent: (id) => api.get(backendUrl + `/setting-events/${id}`),
145
+ suggestSettingEvents: () => api.post(backendUrl + '/setting-events/suggest'),
146
+ createSettingEvent: (data) => api.post(backendUrl + '/setting-events', data),
140
147
  updateSettingEvent: (id, data) => {
141
148
  if (data instanceof FormData) {
142
- return api.post(`/api/rewardplay/setting-events/${id}`, data)
149
+ return api.post(backendUrl + `/setting-events/${id}`, data)
143
150
  }
144
- return api.put(`/api/rewardplay/setting-events/${id}`, data)
151
+ return api.put(backendUrl + `/setting-events/${id}`, data)
145
152
  },
146
- deleteSettingEvent: (id) => api.delete(`/api/rewardplay/setting-events/${id}`),
153
+ deleteSettingEvent: (id) => api.delete(backendUrl + `/setting-events/${id}`),
147
154
 
148
155
  // Setting Shop Items (Manage)
149
- getSettingShopItems: (params) => api.get('/api/rewardplay/setting-shop-items', { params }),
150
- getSettingShopItem: (id) => api.get(`/api/rewardplay/setting-shop-items/${id}`),
151
- suggestSettingShopItems: () => api.post('/api/rewardplay/setting-shop-items/suggest'),
152
- createSettingShopItem: (data) => api.post('/api/rewardplay/setting-shop-items', data),
153
- updateSettingShopItem: (id, data) => api.put(`/api/rewardplay/setting-shop-items/${id}`, data),
154
- deleteSettingShopItem: (id) => api.delete(`/api/rewardplay/setting-shop-items/${id}`),
156
+ getSettingShopItems: (params) => api.get(backendUrl + '/setting-shop-items', { params }),
157
+ getSettingShopItem: (id) => api.get(backendUrl + `/setting-shop-items/${id}`),
158
+ suggestSettingShopItems: () => api.post(backendUrl + '/setting-shop-items/suggest'),
159
+ createSettingShopItem: (data) => api.post(backendUrl + '/setting-shop-items', data),
160
+ updateSettingShopItem: (id, data) => api.put(backendUrl + `/setting-shop-items/${id}`, data),
161
+ deleteSettingShopItem: (id) => api.delete(backendUrl + `/setting-shop-items/${id}`),
155
162
 
156
163
  // Player Daily Rewards & Bag
157
- getPlayerDailyRewardState: () => api.get('/api/rewardplay/player/daily-rewards'), // Includes stack info
158
- collectDailyReward: () => api.post('/api/rewardplay/player/daily-rewards/collect'),
159
- getPlayerBag: () => api.get('/api/rewardplay/player/bag'),
160
- saveGears: (gears) => api.post('/api/rewardplay/player/bag/gears', { gears }),
164
+ getPlayerDailyRewardState: () => api.get(backendUrl + '/player/daily-rewards'), // Includes stack info
165
+ collectDailyReward: () => api.post(backendUrl + '/player/daily-rewards/collect'),
166
+ getPlayerBag: () => api.get(backendUrl + '/player/bag'),
167
+ saveGears: (gears) => api.post(backendUrl + '/player/bag/gears', { gears }),
161
168
  openBox: (userBagItemId, quantity = 1) =>
162
- api.post('/api/rewardplay/player/bag/open-box', { user_bag_item_id: userBagItemId, quantity: Math.max(1, Math.min(parseInt(quantity, 10) || 1, 99)) }),
169
+ api.post(backendUrl + '/player/bag/open-box', { user_bag_item_id: userBagItemId, quantity: Math.max(1, Math.min(parseInt(quantity, 10) || 1, 99)) }),
163
170
 
164
171
  // Player Events (active events for popup)
165
- getPlayerEvents: () => api.get('/api/rewardplay/player/events'),
172
+ getPlayerEvents: () => api.get(backendUrl + '/player/events'),
166
173
 
167
174
  // Player Shop (active shop items + purchase)
168
- getPlayerShop: () => api.get('/api/rewardplay/player/shop'),
175
+ getPlayerShop: () => api.get(backendUrl + '/player/shop'),
169
176
  purchaseShopItem: (shopItemId, quantity = 1) =>
170
- api.post('/api/rewardplay/player/shop/purchase', { shop_item_id: shopItemId, quantity }),
177
+ api.post(backendUrl + '/player/shop/purchase', { shop_item_id: shopItemId, quantity }),
171
178
  }
172
179
  }
173
180
 
package/src/index.js CHANGED
@@ -9,11 +9,16 @@ import * as StatHelpers from './utils/statHelpers'
9
9
  * Install game module
10
10
  * @param {Object} app - Vue app instance
11
11
  * @param {Object} options - Configuration
12
+ * @param {string} options.coreUrl - Core API URL (required)
12
13
  * @param {string} options.backendUrl - Backend API URL (required)
13
14
  * @param {string} options.token - RewardPlay token (required)
14
15
  */
15
16
  export function installGameModule(app, options = {}) {
16
- const { backendUrl, token } = options
17
+ const { coreUrl, backendUrl, token } = options
18
+
19
+ if (!coreUrl) {
20
+ throw new Error('Game Module: coreUrl is required')
21
+ }
17
22
 
18
23
  if (!backendUrl) {
19
24
  throw new Error('Game Module: backendUrl is required')
@@ -23,10 +28,15 @@ export function installGameModule(app, options = {}) {
23
28
  throw new Error('Game Module: token is required')
24
29
  }
25
30
 
26
- const gameApi = createGameApi(backendUrl, token)
31
+ const gameApi = createGameApi(coreUrl, backendUrl, token)
27
32
 
28
33
  app.provide('gameApi', gameApi)
29
34
  app.config.globalProperties.$gameApi = gameApi
35
+
36
+ // Provide coreUrl so components (e.g., RewardPlayPage) can consume it without re-passing
37
+ app.provide('coreUrl', coreUrl)
38
+ app.config.globalProperties.$coreUrl = coreUrl
39
+
30
40
  // Provide backendUrl so components (e.g., RewardPlayPage) can consume it without re-passing
31
41
  app.provide('backendUrl', backendUrl)
32
42
  app.config.globalProperties.$backendUrl = backendUrl
@@ -48,7 +48,6 @@
48
48
  <label>{{ t('page.manageSetting.manageZones.form.name') || 'Name' }}</label>
49
49
  <input v-model="formData.name" type="text" required />
50
50
  </div>
51
- <!-- server_id is determined by server context; no input required -->
52
51
  </div>
53
52
  <div class="modal-footer">
54
53
  <button class="btn-secondary" @click="closeModal">{{ t('page.manageSetting.manageZones.cancel') || 'Cancel' }}</button>