diff --git a/.env.development b/.env.development index e5047a3..713116c 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ -VITE_APP_VERSION="3.0.8-shrimplinks" +VITE_APP_VERSION="3.0.9" 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 94175a8..3e08d63 100644 --- a/.env.production +++ b/.env.production @@ -1,4 +1,4 @@ -VITE_APP_VERSION="3.0.8-shrimplinks" +VITE_APP_VERSION="3.0.9" 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/data-sources/changelog.json b/public/data-sources/changelog.json index 51767f3..546e36b 100644 --- a/public/data-sources/changelog.json +++ b/public/data-sources/changelog.json @@ -7,5 +7,6 @@ "3.0.6": ["- (Major) Replace non-standard game cards with a standardized and new header card. May break some layouts so PLEASE REPORT BUGS!", "- (Feature) Create song detail page, not yet completed or reactive.", "- (Bugfix) Fix issue where deleteSession fails if the session has already been deleted.", "- (Minor) Edit ring color on red buttons", "- (Admin) Add Arcades admin page", "- (Bugfix) Fix incorrect prop types for Notes Radar"], "3.0.7": ["- (Major) Song data page now loads data. This data is quite broken for a few games so EXPECT BUGS!", "- (Optimization) Add in table data for games, still missing some data but the basics are complete now."], "3.0.8": ["- (Minor) Added game event options for Classic IIDX versions"], - "3.0.8-shrimplinks": ["- (Bugfix) Fix broken session."] + "3.0.8-shrimplinks": ["- (Bugfix) Fix broken session."], + "3.0.9": ["- (Minor) Add additional data to the dashboard, including today stats and score stats. Add score stats to chart."] } \ No newline at end of file diff --git a/src/components/Charts/chart.config.js b/src/components/Charts/chart.config.js index 453e2d7..9165f47 100644 --- a/src/components/Charts/chart.config.js +++ b/src/components/Charts/chart.config.js @@ -27,6 +27,48 @@ const datasetObject = (color, points) => { }; }; +const datasetRecordObject = (color, points) => { + return { + fill: false, + borderColor: chartColors.default[color], + borderWidth: 2, + borderDash: [], + borderDashOffset: 0.0, + pointBackgroundColor: chartColors.default[color], + pointBorderColor: "rgba(255,255,255,0)", + pointHoverBackgroundColor: chartColors.default[color], + pointBorderWidth: 20, + pointHoverRadius: 4, + pointHoverBorderWidth: 15, + pointRadius: 4, + data: points, + tension: 0.5, + cubicInterpolationMode: "default", + label: "Records", + }; +}; + +const datasetAttemptObject = (color, points) => { + return { + fill: false, + borderColor: chartColors.default[color], + borderWidth: 2, + borderDash: [], + borderDashOffset: 0.0, + pointBackgroundColor: chartColors.default[color], + pointBorderColor: "rgba(255,255,255,0)", + pointHoverBackgroundColor: chartColors.default[color], + pointBorderWidth: 20, + pointHoverRadius: 4, + pointHoverBorderWidth: 15, + pointRadius: 4, + data: points, + tension: 0.5, + cubicInterpolationMode: "default", + label: "Attempts", + }; +}; + const parseArcadeHistory = (users) => { const groupByDay = (timestamps) => { const dayMap = {}; @@ -67,7 +109,7 @@ const parseArcadeHistory = (users) => { return { labels: last14Days, data: playCounts }; }; -export const generateChartData = (users) => { +export const generateChartData = (users, scoreStats = null) => { if (!Array.isArray(users) || users.length === 0) { return { labels: [], @@ -76,9 +118,39 @@ export const generateChartData = (users) => { } const { labels, data } = parseArcadeHistory(users); + const baseLabels = labels; + + const groupByDay = (timestamps) => { + const dayMap = {}; + timestamps.forEach((timestamp) => { + const day = new Date(timestamp * 1000).toISOString().split("T")[0]; + dayMap[day] = (dayMap[day] || 0) + 1; + }); + return dayMap; + }; + + const recordsData = []; + const attemptsData = []; + + if (scoreStats?.records && scoreStats?.attempts) { + const recordTimestamps = scoreStats.records.map((r) => r.timestamp); + const attemptTimestamps = scoreStats.attempts.map((a) => a.timestamp); + + const recordCountsByDay = groupByDay(recordTimestamps); + const attemptCountsByDay = groupByDay(attemptTimestamps); + + baseLabels.forEach((day) => { + recordsData.push(recordCountsByDay[day] || 0); + attemptsData.push(attemptCountsByDay[day] || 0); + }); + } return { - labels, - datasets: [datasetObject("info", data)], + labels: baseLabels, + datasets: [ + datasetObject("info", data), + datasetRecordObject("primary", recordsData), + datasetAttemptObject("danger", attemptsData), + ], }; }; diff --git a/src/stores/main.js b/src/stores/main.js index 03dabfc..16bcc82 100644 --- a/src/stores/main.js +++ b/src/stores/main.js @@ -20,6 +20,7 @@ export const useMainStore = defineStore("main", { userArcades: [], profiles: {}, userCustomize: {}, + userScoreStats: {}, /* Field focus with ctrl+k (to register only once) */ isFieldFocusRegistered: false, @@ -76,6 +77,9 @@ export const useMainStore = defineStore("main", { if (payload.customize) { this.userCustomize = payload.customize; } + if (payload.userScoreStats) { + this.userScoreStats = payload.userScoreStats; + } }, fetch(sampleDataKey) { @@ -268,6 +272,7 @@ export const useMainStore = defineStore("main", { profiles: user.profiles, arcades: user.arcades, customize: user.data?.customize, + userScoreStats: user.scoreStats, }); this.userLoaded = true; return true; diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index 0690f11..e7bbef0 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -1,5 +1,5 @@