Compare commits
12
Commits
71fee1eb11
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da300da460 | ||
|
|
227952a7a3 | ||
|
|
b34d3a5854 | ||
|
|
cddb7e6aff | ||
|
|
f6c6e5e1e9 | ||
|
|
7d06fe8dd5 | ||
|
|
a7620903da | ||
|
|
d6e2b497fa | ||
|
|
8033c58046 | ||
|
|
509d886f17 | ||
|
|
5288d24020 | ||
|
|
724939408c |
No files matched your search
+141
@@ -0,0 +1,141 @@
|
|||||||
|
## 📦 Installation
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- Node.js (v16 or higher)
|
||||||
|
- pnpm (recommended) or npm
|
||||||
|
- SQL database connection
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
1. Clone the repository:
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd studspider-status
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Install dependencies:
|
||||||
|
```bash
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Configure environment variables:
|
||||||
|
Create a `.env` file in the root directory:
|
||||||
|
```env
|
||||||
|
VITE_DATABASE_URL=your_database_connection_string
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Start the development server:
|
||||||
|
```bash
|
||||||
|
pnpm dev
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Build for production:
|
||||||
|
```bash
|
||||||
|
pnpm build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 Usage
|
||||||
|
|
||||||
|
### Development
|
||||||
|
```bash
|
||||||
|
pnpm dev
|
||||||
|
```
|
||||||
|
Access the application at `http://localhost:5173`
|
||||||
|
|
||||||
|
### Production Build
|
||||||
|
```bash
|
||||||
|
pnpm build
|
||||||
|
pnpm preview
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linting
|
||||||
|
```bash
|
||||||
|
pnpm lint
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Features Breakdown
|
||||||
|
|
||||||
|
### Dashboard View
|
||||||
|
- **Recent Changes Panel**: Real-time list of inventory modifications with timestamps
|
||||||
|
- **Statistics Cards**: Quick metrics showing total sets, total themes, and weekly changes
|
||||||
|
- **Theme Distribution Chart**: Visual pie chart displaying inventory breakdown by LEGO theme
|
||||||
|
|
||||||
|
### Navigation
|
||||||
|
- **Dashboard**: Main inventory overview
|
||||||
|
- **Review**: Inventory review and reconciliation
|
||||||
|
- **Statistics**: Detailed analytics and reporting
|
||||||
|
|
||||||
|
## 📁 Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
studspider-status/
|
||||||
|
├── src/
|
||||||
|
│ ├── assets/ # Static assets
|
||||||
|
│ ├── components/ # Reusable Vue components
|
||||||
|
│ │ ├── AppFooter.vue
|
||||||
|
│ │ ├── HelloWorld.vue
|
||||||
|
│ │ └── DynamicPieChart.vue
|
||||||
|
│ ├── layouts/ # Page layout templates
|
||||||
|
│ │ └── default.vue
|
||||||
|
│ ├── pages/ # Application pages (auto-routed)
|
||||||
|
│ │ ├── index.vue # Dashboard home page
|
||||||
|
│ │ ├── demo.vue # Component demo page
|
||||||
|
│ │ ├── stats.vue # Statistics page
|
||||||
|
│ │ └── review.vue # Review page
|
||||||
|
│ ├── plugins/ # Vue plugins (Vuetify, Router, etc.)
|
||||||
|
│ │ ├── index.js
|
||||||
|
│ │ └── vuetify.js
|
||||||
|
│ ├── router/ # Vue Router configuration
|
||||||
|
│ │ └── index.js
|
||||||
|
│ ├── stores/ # Pinia state management
|
||||||
|
│ │ ├── app.js
|
||||||
|
│ │ └── index.js
|
||||||
|
│ ├── styles/ # Global styles and SCSS
|
||||||
|
│ │ └── settings.scss
|
||||||
|
│ ├── App.vue # Root application component
|
||||||
|
│ └── main.js # Application entry point
|
||||||
|
├── public/ # Public static files
|
||||||
|
├── .env # Environment variables (not committed)
|
||||||
|
├── package.json # Project dependencies
|
||||||
|
├── vite.config.mjs # Vite configuration
|
||||||
|
└── README.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Adding New Pages
|
||||||
|
1. Create a new `.vue` file in `src/pages/`
|
||||||
|
2. Add route metadata at the bottom:
|
||||||
|
```vue
|
||||||
|
<route lang="yaml">
|
||||||
|
name: yourpage
|
||||||
|
layout: default
|
||||||
|
</route>
|
||||||
|
```
|
||||||
|
3. Add navigation item in `App.vue`:
|
||||||
|
```vue
|
||||||
|
<v-list-item
|
||||||
|
prepend-icon="mdi-your-icon"
|
||||||
|
title="Your Page"
|
||||||
|
value="yourpage"
|
||||||
|
to="/yourpage"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Modifying Themes
|
||||||
|
Edit the color palette in component files or update Vuetify theme settings in `src/plugins/vuetify.js`.
|
||||||
|
|
||||||
|
|
||||||
|
### Development Server Won't Start
|
||||||
|
```bash
|
||||||
|
# Clear node modules and reinstall
|
||||||
|
rm -rf node_modules
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# Clear Vite cache
|
||||||
|
rm -rf .vite
|
||||||
|
```
|
||||||
|
|
||||||
|
### Routing Not Working
|
||||||
|
- Ensure all pages have proper route metadata
|
||||||
|
- Check that `unplugin-vue-router` is configured in `vite.config.mjs`
|
||||||
|
- Verify the layout system is properly set up
|
||||||
@@ -1,79 +1,14 @@
|
|||||||
# Vuetify (Default)
|
# studspider-status
|
||||||
|
|
||||||
This is the official scaffolding tool for Vuetify, designed to give you a head start in building your new Vuetify application. It sets up a base template with all the necessary configurations and standard directory structure, enabling you to begin development without the hassle of setting up the project from scratch.
|
`studspider-status` is the frontend of `studspider`.
|
||||||
|
|
||||||
## ❗️ Important Links
|
|
||||||
|
|
||||||
- 📄 [Docs](https://vuetifyjs.com/)
|
built with
|
||||||
- 🚨 [Issues](https://issues.vuetifyjs.com/)
|
|
||||||
- 🏬 [Store](https://store.vuetifyjs.com/)
|
|
||||||
- 🎮 [Playground](https://play.vuetifyjs.com/)
|
|
||||||
- 💬 [Discord](https://community.vuetifyjs.com)
|
|
||||||
|
|
||||||
## 💿 Install
|
- vue 3
|
||||||
|
- vuetify
|
||||||
|
- apexcharts
|
||||||
|
|
||||||
Set up your project using your preferred package manager. Use the corresponding command to install the dependencies:
|
license
|
||||||
|
|
||||||
| Package Manager | Command |
|
- MPL 2.0
|
||||||
|---------------------------------------------------------------|----------------|
|
|
||||||
| [yarn](https://yarnpkg.com/getting-started) | `yarn install` |
|
|
||||||
| [npm](https://docs.npmjs.com/cli/v7/commands/npm-install) | `npm install` |
|
|
||||||
| [pnpm](https://pnpm.io/installation) | `pnpm install` |
|
|
||||||
| [bun](https://bun.sh/#getting-started) | `bun install` |
|
|
||||||
|
|
||||||
After completing the installation, your environment is ready for Vuetify development.
|
|
||||||
|
|
||||||
## ✨ Features
|
|
||||||
|
|
||||||
- 🖼️ **Optimized Front-End Stack**: Leverage the latest Vue 3 and Vuetify 3 for a modern, reactive UI development experience. [Vue 3](https://v3.vuejs.org/) | [Vuetify 3](https://vuetifyjs.com/en/)
|
|
||||||
- 🗃️ **State Management**: Integrated with [Pinia](https://pinia.vuejs.org/), the intuitive, modular state management solution for Vue.
|
|
||||||
- 🚦 **Routing and Layouts**: Utilizes Vue Router for SPA navigation and vite-plugin-vue-layouts for organizing Vue file layouts. [Vue Router](https://router.vuejs.org/) | [vite-plugin-vue-layouts](https://github.com/JohnCampionJr/vite-plugin-vue-layouts)
|
|
||||||
- ⚡ **Next-Gen Tooling**: Powered by Vite, experience fast cold starts and instant HMR (Hot Module Replacement). [Vite](https://vitejs.dev/)
|
|
||||||
- 🧩 **Automated Component Importing**: Streamline your workflow with unplugin-vue-components, automatically importing components as you use them. [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components)
|
|
||||||
|
|
||||||
These features are curated to provide a seamless development experience from setup to deployment, ensuring that your Vuetify application is both powerful and maintainable.
|
|
||||||
|
|
||||||
## 💡 Usage
|
|
||||||
|
|
||||||
This section covers how to start the development server and build your project for production.
|
|
||||||
|
|
||||||
### Starting the Development Server
|
|
||||||
|
|
||||||
To start the development server with hot-reload, run the following command. The server will be accessible at [http://localhost:3000](http://localhost:3000):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn dev
|
|
||||||
```
|
|
||||||
|
|
||||||
(Repeat for npm, pnpm, and bun with respective commands.)
|
|
||||||
|
|
||||||
> Add NODE_OPTIONS='--no-warnings' to suppress the JSON import warnings that happen as part of the Vuetify import mapping. If you are on Node [v21.3.0](https://nodejs.org/en/blog/release/v21.3.0) or higher, you can change this to NODE_OPTIONS='--disable-warning=5401'. If you don't mind the warning, you can remove this from your package.json dev script.
|
|
||||||
|
|
||||||
### Building for Production
|
|
||||||
|
|
||||||
To build your project for production, use:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn build
|
|
||||||
```
|
|
||||||
|
|
||||||
(Repeat for npm, pnpm, and bun with respective commands.)
|
|
||||||
|
|
||||||
Once the build process is completed, your application will be ready for deployment in a production environment.
|
|
||||||
|
|
||||||
## 💪 Support Vuetify Development
|
|
||||||
|
|
||||||
This project is built with [Vuetify](https://vuetifyjs.com/en/), a UI Library with a comprehensive collection of Vue components. Vuetify is an MIT licensed Open Source project that has been made possible due to the generous contributions by our [sponsors and backers](https://vuetifyjs.com/introduction/sponsors-and-backers/). If you are interested in supporting this project, please consider:
|
|
||||||
|
|
||||||
- [Requesting Enterprise Support](https://support.vuetifyjs.com/)
|
|
||||||
- [Sponsoring John on Github](https://github.com/users/johnleider/sponsorship)
|
|
||||||
- [Sponsoring Kael on Github](https://github.com/users/kaelwd/sponsorship)
|
|
||||||
- [Supporting the team on Open Collective](https://opencollective.com/vuetify)
|
|
||||||
- [Becoming a sponsor on Patreon](https://www.patreon.com/vuetify)
|
|
||||||
- [Becoming a subscriber on Tidelift](https://tidelift.com/subscription/npm/vuetify)
|
|
||||||
- [Making a one-time donation with Paypal](https://paypal.me/vuetify)
|
|
||||||
|
|
||||||
## 📑 License
|
|
||||||
[MIT](http://opensource.org/licenses/MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2016-present Vuetify, LLC
|
|
||||||
+4
-2
@@ -2,9 +2,11 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||||
|
<link rel="alternate icon" type="image/png" href="/favicon.png">
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Welcome to Vuetify 3</title>
|
<title>Studspider</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "edderkop-status",
|
"name": "studspider-status",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 91 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>spider</title><path d="M21.29 16.71L22.71 15.29L19.5 12.11L16.5 11.26L18.41 11L22.6 7.8L21.4 6.2L17.59 9.05L14.91 9.5L18.11 6.31L17 1.76L15 2.24L15.86 5.69L14.76 6.83A3 3 0 0 0 9.24 6.83L8.11 5.69L9 2.24L7 1.76L5.89 6.31L9.09 9.5L6.4 9.05L2.6 6.2L1.4 7.8L5.6 11L7.46 11.31L4.46 12.16L1.29 15.29L2.71 16.71L5.5 13.89L7.87 13.22L4 16.54V22H6V17.46L7.56 16.12A4.5 4.5 0 0 0 16.44 16.12L18 17.46V22H20V16.54L16.13 13.22L18.5 13.89Z" /></svg>
|
||||||
|
After Width: | Height: | Size: 504 B |
+30
-111
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-app id="inspire">
|
<v-app id="studspider-dashboard">
|
||||||
<v-navigation-drawer v-model="drawer">
|
<v-navigation-drawer v-model="drawer" temporary>
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
prepend-icon="mdi-view-dashboard"
|
prepend-icon="mdi-view-dashboard"
|
||||||
@@ -8,134 +8,47 @@
|
|||||||
value="dashboard"
|
value="dashboard"
|
||||||
to="/"
|
to="/"
|
||||||
/>
|
/>
|
||||||
|
<v-list-item
|
||||||
|
prepend-icon="mdi-toy-brick-plus"
|
||||||
|
title="Changes"
|
||||||
|
value="changes"
|
||||||
|
to="/changes"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<v-list-item
|
||||||
|
prepend-icon="mdi-toy-brick-search"
|
||||||
|
title="Review"
|
||||||
|
value="review"
|
||||||
|
to="/review"
|
||||||
|
/>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
prepend-icon="mdi-chart-box"
|
prepend-icon="mdi-chart-box"
|
||||||
title="Statistics"
|
title="Statistics"
|
||||||
value="stats"
|
value="stats"
|
||||||
to="/stats"
|
to="/stats"
|
||||||
/>
|
/>
|
||||||
<v-list-item
|
|
||||||
prepend-icon="mdi-code-tags"
|
|
||||||
title="Demo"
|
|
||||||
value="demo"
|
|
||||||
to="/demo"
|
|
||||||
color="primary"
|
|
||||||
/>
|
|
||||||
<v-divider class="my-2"></v-divider>
|
<v-divider class="my-2"></v-divider>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
prepend-icon="mdi-cog"
|
prepend-icon="mdi-sync-off"
|
||||||
title="Settings"
|
title="Run sync (DISABLED)"
|
||||||
value="settings"
|
value="settings"
|
||||||
to="/settings"
|
to="/settings"
|
||||||
|
disabled="true"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-navigation-drawer>
|
</v-navigation-drawer>
|
||||||
|
|
||||||
<v-app-bar>
|
<v-app-bar density="compact">
|
||||||
<v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
|
<v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
|
||||||
|
|
||||||
<v-app-bar-title>Dashboard</v-app-bar-title>
|
<v-app-bar-title><a href="/">Dashboard</a></v-app-bar-title>
|
||||||
|
|
||||||
</v-app-bar>
|
</v-app-bar>
|
||||||
|
|
||||||
<v-main>
|
<v-main class="pa-0">
|
||||||
<v-container fluid>
|
<router-view />
|
||||||
<v-row>
|
|
||||||
<!-- Column 1: Database Changes List -->
|
|
||||||
<v-col cols="12" md="3">
|
|
||||||
<v-card class="mb-4">
|
|
||||||
<v-card-title>Recent Changes</v-card-title>
|
|
||||||
<v-list>
|
|
||||||
<v-list-item
|
|
||||||
v-for="(change, index) in recentChanges"
|
|
||||||
:key="index"
|
|
||||||
:title="change.title"
|
|
||||||
:subtitle="change.timestamp"
|
|
||||||
:prepend-icon="change.type === 'add' ? 'mdi-plus-circle' : change.type === 'remove' ? 'mdi-minus-circle' : 'mdi-pencil'"
|
|
||||||
>
|
|
||||||
<template v-slot:prepend>
|
|
||||||
<v-icon :color="change.type === 'add' ? 'success' : change.type === 'remove' ? 'error' : 'info'">
|
|
||||||
{{ change.type === 'add' ? 'mdi-plus-circle' : change.type === 'remove' ? 'mdi-minus-circle' : 'mdi-pencil' }}
|
|
||||||
</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
|
|
||||||
<!-- Column 2: Graphs and Statistics -->
|
|
||||||
<v-col cols="12" md="6">
|
|
||||||
<v-card class="mb-4">
|
|
||||||
<v-card-title>Changes Over Time</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-sheet height="300">
|
|
||||||
<!-- Placeholder for line chart - you can add your preferred charting library here -->
|
|
||||||
<v-responsive class="text-center">
|
|
||||||
Line Chart Coming Soon
|
|
||||||
</v-responsive>
|
|
||||||
</v-sheet>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
|
|
||||||
<v-card class="mb-4">
|
|
||||||
<v-card-title>Statistics</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="12" md="4">
|
|
||||||
<v-card variant="outlined">
|
|
||||||
<v-card-text class="text-center">
|
|
||||||
<div class="text-h3">{{ totalSets }}</div>
|
|
||||||
<div class="text-subtitle-1">Total Sets</div>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" md="4">
|
|
||||||
<v-card variant="outlined">
|
|
||||||
<v-card-text class="text-center">
|
|
||||||
<div class="text-h3">{{ totalThemes }}</div>
|
|
||||||
<div class="text-subtitle-1">Total Themes</div>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" md="4">
|
|
||||||
<v-card variant="outlined">
|
|
||||||
<v-card-text class="text-center">
|
|
||||||
<div class="text-h3">{{ changesThisWeek }}</div>
|
|
||||||
<div class="text-subtitle-1">Changes This Week</div>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
|
|
||||||
<!-- Column 3: Pie Chart -->
|
|
||||||
<v-col cols="12" md="3">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>Theme Distribution</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-pie
|
|
||||||
title="Sets by theme"
|
|
||||||
animation
|
|
||||||
legend
|
|
||||||
:palette="['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEEAD',
|
|
||||||
'#D4A5A5', '#9B59B6', '#3498DB', '#E74C3C', '#2ECC71',
|
|
||||||
'#F1C40F', '#1ABC9C', '#D35400', '#C0392B', '#8E44AD',
|
|
||||||
'#2980B9', '#27AE60', '#F39C12', '#16A085', '#E67E22',
|
|
||||||
'#9B59B6', '#2C3E50', '#E84393', '#00B894', '#FD79A8',
|
|
||||||
'#6C5CE7', '#A8E6CF', '#DCEDC1', '#FFD3B6', '#FFAAA5',
|
|
||||||
'#FF8B94', '#A8D8EA']"
|
|
||||||
tooltip
|
|
||||||
reveal
|
|
||||||
:items="items"
|
|
||||||
/>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-container>
|
|
||||||
</v-main>
|
</v-main>
|
||||||
</v-app>
|
</v-app>
|
||||||
</template>
|
</template>
|
||||||
@@ -215,9 +128,15 @@
|
|||||||
]
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.v-navigation-drawer {
|
||||||
|
z-index: 999999 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data: () => ({ drawer: null }),
|
data: () => ({ drawer: false }),
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -3,6 +3,9 @@
|
|||||||
app
|
app
|
||||||
height="40"
|
height="40"
|
||||||
>
|
>
|
||||||
|
<div class="text-caption">
|
||||||
|
StudSpider 0.2 <small>(<a href="http://git.traps.moe/ph0sgene/studspider-status/commits/branch/master">{{ gitHash }}</a>)</small>
|
||||||
|
</div>
|
||||||
<a
|
<a
|
||||||
v-for="item in items"
|
v-for="item in items"
|
||||||
:key="item.title"
|
:key="item.title"
|
||||||
@@ -22,21 +25,33 @@
|
|||||||
class="text-caption text-disabled"
|
class="text-caption text-disabled"
|
||||||
style="position: absolute; right: 16px;"
|
style="position: absolute; right: 16px;"
|
||||||
>
|
>
|
||||||
© 2016-{{ (new Date()).getFullYear() }} <span class="d-none d-sm-inline-block">Vuetify, LLC</span>
|
© {{ copyrightYear }} <span class="d-none d-sm-inline-block">PLAY-WELL TEKNOLOGIES</span>
|
||||||
—
|
—
|
||||||
<a
|
<a
|
||||||
class="text-decoration-none on-surface"
|
class="text-decoration-none on-surface"
|
||||||
href="https://vuetifyjs.com/about/licensing/"
|
href="https://www.mozilla.org/en-US/MPL/2.0"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
MIT License
|
MPL 2.0
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</v-footer>
|
</v-footer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const gitHash = __GIT_COMMIT_HASH__
|
||||||
|
|
||||||
|
const copyrightYear = computed(() => {
|
||||||
|
const currentYear = new Date().getFullYear()
|
||||||
|
const startYear = 2025
|
||||||
|
return currentYear > startYear ? `${startYear}-${currentYear}` : `${startYear}`
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
const items = [
|
const items = [
|
||||||
{
|
{
|
||||||
title: 'Vuetify Documentation',
|
title: 'Vuetify Documentation',
|
||||||
@@ -69,6 +84,7 @@
|
|||||||
href: 'https://reddit.com/r/vuetifyjs',
|
href: 'https://reddit.com/r/vuetifyjs',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
*/
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="sass">
|
<style scoped lang="sass">
|
||||||
|
|||||||
Whitespace-only changes.
@@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<v-container fluid class="pa-0 ma-0">
|
||||||
|
<v-card style="height: calc(100vh - 64px); display: flex; flex-direction: column;">
|
||||||
|
<v-card-title class="text-h5">Recent Changes</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text style="overflow-y: auto; flex: 1; padding: 0;">
|
||||||
|
<v-list>
|
||||||
|
<template v-for="(item, index) in changeItems" :key="item.id">
|
||||||
|
<v-list-item
|
||||||
|
:title="item.title"
|
||||||
|
:subtitle="item.description"
|
||||||
|
:prepend-icon="item.icon"
|
||||||
|
three-line
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<v-chip
|
||||||
|
:color="getTypeColor(item.type)"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{{ item.type }}
|
||||||
|
</v-chip>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
|
||||||
|
<v-divider v-if="index < changeItems.length - 1"></v-divider>
|
||||||
|
</template>
|
||||||
|
</v-list>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<route lang="yaml">
|
||||||
|
name: changes
|
||||||
|
layout: default
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
// Sample change items - replace with actual data from your API
|
||||||
|
const changeItems = ref([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: 'Added set 76218 (MV)',
|
||||||
|
description: 'Marvel Spider-Man set added to inventory. Quantity: 5 units. Added 2 minutes ago.',
|
||||||
|
type: 'Add',
|
||||||
|
icon: 'mdi-plus-circle'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: 'Marked for Review 76389 (HP)',
|
||||||
|
description: 'Harry Potter Hogwarts Chamber flagged for manual review. Price mismatch detected. 15 minutes ago.',
|
||||||
|
type: 'Review',
|
||||||
|
icon: 'mdi-pencil'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: 'Removed duplicate 71404 (FR)',
|
||||||
|
description: 'Friends Beach House duplicate entry removed from database. 1 hour ago.',
|
||||||
|
type: 'Remove',
|
||||||
|
icon: 'mdi-minus-circle'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
title: 'Added set 75396 (SW)',
|
||||||
|
description: 'Star Wars AT-TE Walker added to inventory. Quantity: 2 units. 2 hours ago.',
|
||||||
|
type: 'Add',
|
||||||
|
icon: 'mdi-plus-circle'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
title: 'Updated set 75387 (SW)',
|
||||||
|
description: 'Star Wars Millennium Falcon inventory count updated from 3 to 5. 3 hours ago.',
|
||||||
|
type: 'Update',
|
||||||
|
icon: 'mdi-pencil'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
title: 'Added set 60320 (City)',
|
||||||
|
description: 'City Fire Station added to inventory. Quantity: 8 units. 4 hours ago.',
|
||||||
|
type: 'Add',
|
||||||
|
icon: 'mdi-plus-circle'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
title: 'Updated set 42143 (Technic)',
|
||||||
|
description: 'Technic Ferrari price updated to match Square. 5 hours ago.',
|
||||||
|
type: 'Update',
|
||||||
|
icon: 'mdi-pencil'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const getTypeColor = (type) => {
|
||||||
|
switch(type) {
|
||||||
|
case 'Add': return 'success'
|
||||||
|
case 'Remove': return 'error'
|
||||||
|
case 'Update': return 'info'
|
||||||
|
case 'Review': return 'warning'
|
||||||
|
default: return 'default'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -92,6 +92,11 @@
|
|||||||
</v-container>
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<route lang="yaml">
|
||||||
|
name: demo
|
||||||
|
layout: default
|
||||||
|
</route>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const demoItems = [
|
const demoItems = [
|
||||||
{
|
{
|
||||||
|
|||||||
+185
-2
@@ -1,7 +1,190 @@
|
|||||||
<template>
|
<template>
|
||||||
<HelloWorld />
|
<v-container fluid class="pa-0 ma-0">
|
||||||
|
<v-row class="ma-0">
|
||||||
|
<!-- Column 1: Database Changes List -->
|
||||||
|
<v-col cols="12" md="3">
|
||||||
|
<v-card class="mb-4">
|
||||||
|
<v-card-title><a href="changes/">Recent Changes</a></v-card-title>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item
|
||||||
|
v-for="(change, index) in recentChanges"
|
||||||
|
:key="index"
|
||||||
|
:title="change.title"
|
||||||
|
:subtitle="change.timestamp"
|
||||||
|
:prepend-icon="change.type === 'add' ? 'mdi-plus-circle' : change.type === 'remove' ? 'mdi-minus-circle' : 'mdi-pencil'"
|
||||||
|
>
|
||||||
|
<template v-slot:prepend>
|
||||||
|
<v-icon :color="change.type === 'add' ? 'success' : change.type === 'remove' ? 'error' : 'info'">
|
||||||
|
{{ change.type === 'add' ? 'mdi-plus-circle' : change.type === 'remove' ? 'mdi-minus-circle' : 'mdi-pencil' }}
|
||||||
|
</v-icon>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-card>
|
||||||
|
|
||||||
|
<v-card class="mb-4">
|
||||||
|
<v-card-text class="text-center">
|
||||||
|
<div class="text-h4">{{ itemsWaitingForReview }}</div>
|
||||||
|
<div class="text-subtitle-1"><a href="/review">Items waiting for review</a></div>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<!-- Column 2: Graphs and Statistics -->
|
||||||
|
<v-col cols="12" md="6">
|
||||||
|
<v-card class="mb-4">
|
||||||
|
<v-card-title>Changes Over Time</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<v-sheet height="300">
|
||||||
|
<!-- Placeholder for line chart - you can add your preferred charting library here -->
|
||||||
|
<v-responsive class="text-center">
|
||||||
|
Line Chart Coming Soon
|
||||||
|
</v-responsive>
|
||||||
|
</v-sheet>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
|
||||||
|
<v-card class="mb-4">
|
||||||
|
<v-card-title>Statistics</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12" md="4">
|
||||||
|
<v-card variant="outlined">
|
||||||
|
<v-card-text class="text-center">
|
||||||
|
<div class="text-h3">{{ totalSets }}</div>
|
||||||
|
<div class="text-subtitle-1">Total Sets</div>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="12" md="4">
|
||||||
|
<v-card variant="outlined">
|
||||||
|
<v-card-text class="text-center">
|
||||||
|
<div class="text-h3">{{ totalThemes }}</div>
|
||||||
|
<div class="text-subtitle-1">Total Themes</div>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="12" md="4">
|
||||||
|
<v-card variant="outlined" @click="toggleChangesView" style="cursor: pointer;">
|
||||||
|
<v-card-text class="text-center">
|
||||||
|
<div class="text-h3">{{ changesCount }}</div>
|
||||||
|
<div class="text-subtitle-1">
|
||||||
|
{{ changesLabel }}
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<!-- Column 3: Pie Chart -->
|
||||||
|
<v-col cols="12" md="3">
|
||||||
|
<v-card style="max-height: calc(100vh - 100px); display: flex; flex-direction: column;">
|
||||||
|
<v-card-title>Theme Distribution</v-card-title>
|
||||||
|
<v-card-text style="overflow-y: auto; flex: 1;">
|
||||||
|
<v-pie
|
||||||
|
animation
|
||||||
|
legend
|
||||||
|
:palette="['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEEAD',
|
||||||
|
'#D4A5A5', '#9B59B6', '#3498DB', '#E74C3C', '#2ECC71',
|
||||||
|
'#F1C40F', '#1ABC9C', '#D35400', '#C0392B', '#8E44AD',
|
||||||
|
'#2980B9', '#27AE60', '#F39C12', '#16A085', '#E67E22',
|
||||||
|
'#9B59B6', '#2C3E50', '#E84393', '#00B894', '#FD79A8',
|
||||||
|
'#6C5CE7', '#A8E6CF', '#DCEDC1', '#FFD3B6', '#FFAAA5',
|
||||||
|
'#FF8B94', '#A8D8EA']"
|
||||||
|
tooltip
|
||||||
|
reveal
|
||||||
|
:items="items"
|
||||||
|
/>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
//
|
import { ref, computed } from 'vue'
|
||||||
|
|
||||||
|
const drawer = ref(false)
|
||||||
|
|
||||||
|
// Statistics
|
||||||
|
const totalSets = computed(() => items.reduce((acc, item) => acc + item.value, 0))
|
||||||
|
const totalThemes = computed(() => items.length)
|
||||||
|
|
||||||
|
// Dynamic changes metric
|
||||||
|
const changesThisWeek = ref(0) // Set to 0 to test auto-switching, or get from your API
|
||||||
|
const changesThisMonth = ref(45)
|
||||||
|
|
||||||
|
// Automatically show monthly if no weekly activity
|
||||||
|
const changesLabel = computed(() => changesThisWeek.value > 0 ? 'Changes This Week' : 'Changes This Month')
|
||||||
|
const changesCount = computed(() => changesThisWeek.value > 0 ? changesThisWeek.value : changesThisMonth.value)
|
||||||
|
|
||||||
|
// Sample recent changes data
|
||||||
|
const recentChanges = [
|
||||||
|
{
|
||||||
|
title: "Added set 76218 (MV) ",
|
||||||
|
timestamp: "2 minutes ago",
|
||||||
|
type: "add"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Marked for Review 76389 (HP) ",
|
||||||
|
timestamp: "15 minutes ago",
|
||||||
|
type: "update"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Removed duplicate 71404 (FR)",
|
||||||
|
timestamp: "1 hour ago",
|
||||||
|
type: "remove"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Added set 75396 (SW)",
|
||||||
|
timestamp: "2 hours ago",
|
||||||
|
type: "add"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Updated set 75387 (SW)",
|
||||||
|
timestamp: "3 hours ago",
|
||||||
|
type: "update"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{ key: 1, title: "Marvel", value: 1 },
|
||||||
|
{ key: 2, title: "Duplo", value: 1 },
|
||||||
|
{ key: 3, title: "Harry Potter", value: 1 },
|
||||||
|
{ key: 4, title: "Friends", value: 2 }, // Listed twice in original list
|
||||||
|
{ key: 5, title: "Sonic", value: 1 },
|
||||||
|
{ key: 6, title: "Mario", value: 1 },
|
||||||
|
{ key: 7, title: "DC", value: 1 },
|
||||||
|
{ key: 8, title: "Avatar", value: 1 },
|
||||||
|
{ key: 9, title: "Classic", value: 1 },
|
||||||
|
{ key: 10, title: "City", value: 1 },
|
||||||
|
{ key: 11, title: "Fortnite", value: 1 },
|
||||||
|
{ key: 12, title: "Wednesday", value: 1 },
|
||||||
|
{ key: 13, title: "Wicked", value: 1 },
|
||||||
|
{ key: 14, title: "Speed Champs", value: 1 },
|
||||||
|
{ key: 15, title: "Animal Crossing", value: 1 },
|
||||||
|
{ key: 16, title: "Creator", value: 1 },
|
||||||
|
{ key: 17, title: "Ideas", value: 2 }, // Listed twice in original list
|
||||||
|
{ key: 18, title: "Ninjago", value: 1 },
|
||||||
|
{ key: 19, title: "JP", value: 1 },
|
||||||
|
{ key: 20, title: "Star Wars", value: 1 },
|
||||||
|
{ key: 21, title: "Architecture", value: 1 },
|
||||||
|
{ key: 22, title: "Icons", value: 1 },
|
||||||
|
{ key: 23, title: "Dots", value: 1 },
|
||||||
|
{ key: 24, title: "Dreamzzz", value: 1 },
|
||||||
|
{ key: 25, title: "One Piece", value: 1 },
|
||||||
|
{ key: 26, title: "Bluey", value: 1 },
|
||||||
|
{ key: 27, title: "Disney", value: 1 },
|
||||||
|
{ key: 28, title: "Technic", value: 1 },
|
||||||
|
{ key: 29, title: "Art", value: 1 },
|
||||||
|
{ key: 30, title: "Botanicals", value: 1 }
|
||||||
|
]
|
||||||
|
|
||||||
|
const itemsWaitingForReview = ref(7)
|
||||||
</script>
|
</script>
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
<template>
|
||||||
|
<v-container fluid class="pa-0 ma-0">
|
||||||
|
<v-card style="height: calc(100vh - 64px); display: flex; flex-direction: column;">
|
||||||
|
<v-card-title class="text-h5">Manual Review Items</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text style="overflow-y: auto; flex: 1; padding: 0;">
|
||||||
|
<v-list>
|
||||||
|
<template v-for="(item, index) in reviewItems" :key="item.id">
|
||||||
|
<v-list-item
|
||||||
|
:title="item.title"
|
||||||
|
:subtitle="item.description"
|
||||||
|
:prepend-icon="item.icon"
|
||||||
|
three-line
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<v-chip
|
||||||
|
:color="getStatusColor(item.status)"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{{ item.status }}
|
||||||
|
</v-chip>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
|
||||||
|
<v-divider v-if="index < reviewItems.length - 1"></v-divider>
|
||||||
|
</template>
|
||||||
|
</v-list>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<route lang="yaml">
|
||||||
|
name: review
|
||||||
|
layout: default
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
// Sample review items - replace with actual data from your API
|
||||||
|
const reviewItems = ref([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: 'LEGO Set 76218 - Marvel Spider-Man',
|
||||||
|
description: 'Inventory mismatch detected. Square shows 5 units, database shows 3 units.',
|
||||||
|
status: 'Pending',
|
||||||
|
icon: 'mdi-alert-circle'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: 'LEGO Set 76389 - Harry Potter Hogwarts Chamber',
|
||||||
|
description: 'Price discrepancy found. Needs verification.',
|
||||||
|
status: 'Urgent',
|
||||||
|
icon: 'mdi-alert'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: 'LEGO Set 71404 - Friends Beach House',
|
||||||
|
description: 'Duplicate entry detected in system.',
|
||||||
|
status: 'Review',
|
||||||
|
icon: 'mdi-file-document-multiple'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
title: 'LEGO Set 75396 - Star Wars AT-TE Walker',
|
||||||
|
description: 'New set added to Square but not in Brickset database.',
|
||||||
|
status: 'Pending',
|
||||||
|
icon: 'mdi-plus-circle'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
title: 'LEGO Set 75387 - Star Wars Millennium Falcon',
|
||||||
|
description: 'Stock level adjustment required.',
|
||||||
|
status: 'Review',
|
||||||
|
icon: 'mdi-pencil'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const getStatusColor = (status) => {
|
||||||
|
switch(status) {
|
||||||
|
case 'Urgent': return 'error'
|
||||||
|
case 'Pending': return 'warning'
|
||||||
|
case 'Review': return 'info'
|
||||||
|
default: return 'default'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<v-container>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>Statistics Page</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
This is the statistics page content
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<route lang="yaml">
|
||||||
|
name: stats
|
||||||
|
layout: default
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// Add any statistics page specific logic here
|
||||||
|
</script>
|
||||||
+19
-1
@@ -11,9 +11,23 @@ import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
|
|||||||
// Utilities
|
// Utilities
|
||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import { fileURLToPath, URL } from 'node:url'
|
import { fileURLToPath, URL } from 'node:url'
|
||||||
|
import { execSync } from 'child_process'
|
||||||
|
|
||||||
|
// Get git commit hash
|
||||||
|
const getGitHash = () => {
|
||||||
|
try {
|
||||||
|
return execSync('git rev-parse --short HEAD').toString().trim()
|
||||||
|
} catch (e) {
|
||||||
|
return 'unknown'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
define: {
|
||||||
|
'__GIT_COMMIT_HASH__': JSON.stringify(getGitHash()),
|
||||||
|
'process.env': {}
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
VueRouter(),
|
VueRouter(),
|
||||||
Layouts(),
|
Layouts(),
|
||||||
@@ -59,7 +73,6 @@ export default defineConfig({
|
|||||||
'unplugin-vue-router/data-loaders/basic',
|
'unplugin-vue-router/data-loaders/basic',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
define: { 'process.env': {} },
|
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': fileURLToPath(new URL('src', import.meta.url)),
|
'@': fileURLToPath(new URL('src', import.meta.url)),
|
||||||
@@ -76,5 +89,10 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3000,
|
||||||
|
host: true,
|
||||||
|
allowedHosts: [
|
||||||
|
'studspider.sh',
|
||||||
|
'.studspider.sh',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
Reference in new issue
Block a user