diff --git a/.env.development b/.env.development index 6ef26bcf..0651a9fe 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ -VITE_APP_VERSION="3.0.15" +VITE_APP_VERSION="3.0.16" VITE_API_URL="http://10.5.7.5:8000/" VITE_API_KEY="your_api_key_should_be_here" VITE_ASSET_PATH="/assets" diff --git a/.env.production b/.env.production index 2985b08a..09e2a6bb 100644 --- a/.env.production +++ b/.env.production @@ -1,4 +1,4 @@ -VITE_APP_VERSION="3.0.15" +VITE_APP_VERSION="3.0.16" VITE_API_URL="https://restfulsleep.phaseii.network" VITE_API_KEY="your_api_key_should_be_here" VITE_ASSET_PATH="https://cdn.phaseii.network/file/PhaseII/web-assets" diff --git a/public/assets/card/nost.webp b/public/assets/card/nost.webp index 0cb57dce..a84ba433 100644 Binary files a/public/assets/card/nost.webp and b/public/assets/card/nost.webp differ diff --git a/public/assets/games/nost/card/1.webp b/public/assets/games/nost/card/1.webp new file mode 100644 index 00000000..56f22e53 Binary files /dev/null and b/public/assets/games/nost/card/1.webp differ diff --git a/public/assets/games/nost/card/2.webp b/public/assets/games/nost/card/2.webp new file mode 100644 index 00000000..830e23a4 Binary files /dev/null and b/public/assets/games/nost/card/2.webp differ diff --git a/public/assets/games/nost/card/3.webp b/public/assets/games/nost/card/3.webp new file mode 100644 index 00000000..f1a17153 Binary files /dev/null and b/public/assets/games/nost/card/3.webp differ diff --git a/public/assets/icon/nost.webp b/public/assets/icon/nost.webp index 04e19403..ab47e007 100644 Binary files a/public/assets/icon/nost.webp and b/public/assets/icon/nost.webp differ diff --git a/public/data-sources/changelog.json b/public/data-sources/changelog.json index 114f8374..f4d27196 100644 --- a/public/data-sources/changelog.json +++ b/public/data-sources/changelog.json @@ -14,5 +14,6 @@ "3.0.12": ["- (Feature) Add new game event settings to SILENT SCOPE: BONE EATER and beatmaniaIIDX EPOLIS."], "3.0.13": ["- (Feature) Add new game event settings to beatmaniaIIDX EPOLIS."], "3.0.14": ["- (Minor) Fix footer buttons on tables, add generic export table button for every table."], - "3.0.15": ["- (Minor) Add beta support for Pinky Crush, clean up gameDB a little.", "- (Optimization) Convert dashboard to a more modular backend.", "- (Bugfix) Fix warnings on auth pages."] + "3.0.15": ["- (Minor) Add beta support for Pinky Crush, clean up gameDB a little.", "- (Optimization) Convert dashboard to a more modular backend.", "- (Bugfix) Fix warnings on auth pages."], + "3.0.16": ["- (Major) Add multiple new admin features for network management.", "- (Optimization) Optimize backend for arcade operations.", "- (Bugfix) Fix possible backend issues with better type enforcing.", "- (Bugfix) Fix event data and game data for IIDX Pinky Crush.", "- (Minor) Add assets for Nostalgia."] } \ No newline at end of file diff --git a/src/constants/gameOptions/iidxOptions.js b/src/constants/gameOptions/iidxOptions.js index 67ae54b0..3e155672 100644 --- a/src/constants/gameOptions/iidxOptions.js +++ b/src/constants/gameOptions/iidxOptions.js @@ -423,14 +423,9 @@ export const IIDXOptions = { type: "Array", options: [ { id: 0, label: "No Event" }, - { id: 1, label: "MY POLIS DESIGNER (MAP 1)" }, - { id: 2, label: "MY POLIS DESIGNER (MAP 2)" }, - { id: 3, label: "MY POLIS DESIGNER (MAP 3)" }, - { id: 4, label: "MY POLIS DESIGNER (MAP FINAL)" }, - { id: 5, label: "EPOLIS RESTORATION (SYSTEM A)" }, - { id: 6, label: "EPOLIS RESTORATION (SYSTEM B)" }, - { id: 7, label: "EPOLIS RESTORATION (SYSTEM C)" }, - { id: 8, label: "EPOLIS RESTORATION (SYSTEM D + X)" }, + { id: 1, label: "Pinky Jump UP! (MAP 1)" }, + { id: 2, label: "Pinky Jump UP! (MAP 2)" }, + { id: 3, label: "Pinky Jump UP! (MAP 3)" }, ], }, { diff --git a/src/constants/index.js b/src/constants/index.js index d3fb5324..957d8282 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -1407,7 +1407,7 @@ export const gameData = [ }, { id: VersionConstants.IIDX_PINKY_CRUSH, - label: "PINKY CRUSH", + label: "Pinky Crush", maxRivals: 5, }, ], diff --git a/src/stores/api/admin.js b/src/stores/api/admin.js index 8196b5a8..3089bb6c 100644 --- a/src/stores/api/admin.js +++ b/src/stores/api/admin.js @@ -42,6 +42,20 @@ export async function checkPCBID(PCBID) { } } +export async function APIAdminCreateMachine(arcadeId, newMachine) { + try { + const data = await mainStore.callApi( + `/admin/arcade/${arcadeId}/machine`, + "POST", + newMachine + ); + return data; + } catch (error) { + console.log("Error adding machine:", error); + throw error; + } +} + export async function APIOnboardArcade(newArcade) { try { const data = await mainStore.callApi( @@ -56,6 +70,20 @@ export async function APIOnboardArcade(newArcade) { } } +export async function APIAdminUpdateArcade(arcadeId, newArcade) { + try { + const data = await mainStore.callApi( + `/admin/arcade/${arcadeId}`, + "POST", + newArcade + ); + return data; + } catch (error) { + console.log("Error updating arcade:", error); + throw error; + } +} + export async function APIAdminMaintenancePeriods() { try { const data = await mainStore.callApi(`/admin/maint`); @@ -95,3 +123,33 @@ export async function APIAdminCreateClient(newClient) { throw error; } } + +export async function APIAdminUsers() { + try { + const data = await mainStore.callApi(`/admin/users`); + return data.data; + } catch (error) { + console.log("Error loading users:", error); + throw error; + } +} + +export async function APIAdminNews() { + try { + const data = await mainStore.callApi(`/admin/news`); + return data.data; + } catch (error) { + console.log("Error loading news:", error); + throw error; + } +} + +export async function APIAdminCreateNews(newNews) { + try { + const data = await mainStore.callApi(`/admin/news`, "POST", newNews); + return data; + } catch (error) { + console.log("Error posting news:", error); + throw error; + } +} diff --git a/src/views/Admin/ArcadesView.vue b/src/views/Admin/ArcadesView.vue index 9efc4ad5..24c7cfbd 100644 --- a/src/views/Admin/ArcadesView.vue +++ b/src/views/Admin/ArcadesView.vue @@ -94,6 +94,10 @@ function filterArcades() { if (filterForm.filter) { return arcadeData.value.filter( (arcade) => + arcade.id + .toString() + .toLowerCase() + .includes(filterForm.filter.toLowerCase()) || arcade.name.toLowerCase().includes(filterForm.filter.toLowerCase()) || arcade.description .toLowerCase() @@ -112,30 +116,6 @@ function filterArcades() {

Enter an arcade to manage it

- - - -
-
- -

- Click row to open arcade -

-
-
-
-

Managed by {{ arcade.owners }}

+
+

+ {{ arcade.id }} +

+
-
+
+ + +
+
+ +

+ Click row to open arcade +

+
+
+
+ -import { mdiFlagCheckered, mdiSecurity } from "@mdi/js"; +import { ref, reactive, onMounted } from "vue"; +import { useRouter } from "vue-router"; +import { mdiNewspaper, mdiNewspaperPlus } from "@mdi/js"; import SectionMain from "@/components/SectionMain.vue"; import CardBox from "@/components/CardBox.vue"; -import CardBoxWidget from "@/components/CardBoxWidget.vue"; +import GeneralTable from "@/components/GeneralTable.vue"; import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue"; import SectionTitleLine from "@/components/SectionTitleLine.vue"; +import BaseButton from "@/components/BaseButton.vue"; +import FormField from "@/components/FormField.vue"; +import FormControl from "@/components/FormControl.vue"; + +import { APIAdminNews, APIAdminCreateNews } from "@/stores/api/admin"; + +const $router = useRouter(); +const newsData = ref([]); +const headers = [ + { + text: "Title", + value: "title", + width: 150, + sortable: true, + }, + { + text: "Body", + value: "body", + width: 300, + }, + { + text: "Image URL", + value: "data.img", + width: 300, + }, +]; + +onMounted(async () => { + loadData(); +}); + +async function loadData() { + try { + const data = await APIAdminNews(); + var formattedItems = []; + for (var item of data) { + if (item.timestamp) { + const date = new Date(item.timestamp * 1000); + item.timestamp = date.toLocaleString(); + } + + formattedItems.push(item); + } + + newsData.value = formattedItems; + } catch (error) { + console.error("Failed to fetch news data:", error); + } +} + +const openNews = (item) => { + const arcadeId = item.id; + $router.push(`/news/${arcadeId}`); +}; + +const initNews = { + title: null, + body: null, + data: { img: null }, +}; + +const newNews = reactive({ + ...initNews, +}); + +async function createNews() { + try { + const data = await APIAdminCreateNews(newNews); + newsData.value = data; + } catch (error) { + console.error("Failed to post news:", error); + } + + Object.assign(newNews, initNews); + loadData(); +} diff --git a/src/views/Admin/UsersView.vue b/src/views/Admin/UsersView.vue index 2c61d536..a346e9dd 100644 --- a/src/views/Admin/UsersView.vue +++ b/src/views/Admin/UsersView.vue @@ -1,30 +1,183 @@ diff --git a/src/views/Arcade/ArcadeView.vue b/src/views/Arcade/ArcadeView.vue index 3ea91097..2f86a7f2 100644 --- a/src/views/Arcade/ArcadeView.vue +++ b/src/views/Arcade/ArcadeView.vue @@ -1,7 +1,15 @@