mirror of
https://github.com/PhaseII-eAmusement-Network/PhaseWeb3-Vue.git
synced 2026-03-21 17:54:26 -05:00
Move from MDI to PHI, fix eslint config, add icon animations
This commit is contained in:
parent
f5b9d57e8c
commit
9f1b7c04a6
|
|
@ -1,4 +1,4 @@
|
|||
VITE_APP_VERSION="3.0.24"
|
||||
VITE_APP_VERSION="3.0.25"
|
||||
VITE_API_URL="http://10.5.7.5:8000/"
|
||||
VITE_API_KEY="your_api_key_should_be_here"
|
||||
VITE_ASSET_PATH="/assets"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
VITE_APP_VERSION="3.0.24"
|
||||
VITE_APP_VERSION="3.0.25"
|
||||
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"
|
||||
|
|
|
|||
|
|
@ -1,494 +0,0 @@
|
|||
# Free Laravel Vue 3.x Tailwind 3.x Dashboard
|
||||
|
||||
[](https://justboil.github.io/admin-one-vue-tailwind/)
|
||||
|
||||
This guide will help you integrate your Laravel application with [Admin One - free Vue 3 Tailwind 3 Admin Dashboard with dark mode](https://github.com/justboil/admin-one-vue-tailwind).
|
||||
|
||||
**Admin One** is simple, fast and free Vue.js 3.x Tailwind CSS 3.x admin dashboard with Laravel 9.x integration.
|
||||
|
||||
- Built with **Vue.js 3**, **Tailwind CSS 3** framework & **Composition API**
|
||||
- **Laravel** build tools
|
||||
- **Laravel Breeze** with **Inertia + Vue** stack
|
||||
- **SFC** `<script setup>` [Info](https://v3.vuejs.org/api/sfc-script-setup.html)
|
||||
- **Pinia** state library (official Vuex 5)
|
||||
- **Dark mode**
|
||||
- **Styled** scrollbars
|
||||
- **Production CSS** is only **≈38kb**
|
||||
- Reusable components
|
||||
- Free under MIT License
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Install](#install)
|
||||
- [Copy styles, components and scripts](#copy-styles-components-and-scripts)
|
||||
- [Add pages](#add-pages)
|
||||
- [Fix router links](#fix-router-links)
|
||||
- [Add Inertia-related stuff](#add-inertia-related-stuff)
|
||||
- [Upgrading to Premium version](#upgrading-to-premium-version)
|
||||
- [Optional steps](#optional-steps)
|
||||
- [Laravel & Inertia docs](#laravel--inertia-docs)
|
||||
|
||||
## Install
|
||||
|
||||
### Install Laravel
|
||||
|
||||
First, [install Laravel](https://laravel.com/docs/installation) application
|
||||
|
||||
### Install Breeze
|
||||
|
||||
Then `cd` to project dir and install Breeze with Vue option
|
||||
|
||||
```bash
|
||||
composer require laravel/breeze --dev
|
||||
|
||||
php artisan breeze:install vue
|
||||
|
||||
php artisan migrate
|
||||
|
||||
npm install
|
||||
```
|
||||
|
||||
### Install dependencies
|
||||
|
||||
```bash
|
||||
npm i pinia @tailwindcss/line-clamp @mdi/js chart.js numeral -D
|
||||
```
|
||||
|
||||
## Copy styles, components and scripts
|
||||
|
||||
**Before you start,** we recommend to rename Laravel Breeze's original folders (so you'll keep them for future reference) — `resources/js/Components` `resources/js/Layouts` `resources/js/Pages` to something like ComponentsBreeze, LayoutsBreeze, etc.
|
||||
|
||||
Now clone [justboil/admin-one-vue-tailwind](https://github.com/justboil/admin-one-vue-tailwind) project somewhere locally (into any separate folder)
|
||||
|
||||
Next, copy these files **from justboil/admin-one-vue-tailwind project** directory **to laravel project** directory:
|
||||
|
||||
- Copy `tailwind.config.js` to `/`
|
||||
- Copy `src/components` `src/layouts` `src/stores` `src/colors.js` `src/config.js` `src/menuAside.js` `src/menuNavBar.js` `src/styles.js` to `resources/js/`
|
||||
- Copy `.laravel-guide/resources/js/` to `resources/js/`
|
||||
- Delete `resources/css/app.css`
|
||||
- Copy `src/css` to `resources/css`
|
||||
|
||||
### [optional] lowecase vs Capitalized folder names
|
||||
|
||||
Fresh Laravel install with Breeze provides **Capitalized** folder names such as `Components`, `Layouts`, etc. For the sake of simplicity we just follow Vue conventions with lowercase folder names. However, you may opt-in to capitalize folder names:
|
||||
|
||||
- Make sure you've removed original Laravel Breeze's `resources/js/Layouts` and `resources/js/Components` folders
|
||||
- Rename the folders you've copied in the previous section: `resources/js/layouts` to `Layouts`; `components` to `Components`; `stores` to `Stores`
|
||||
- Replace everywhere in imports: `@/layouts/` with `@/Layouts/`; `@/components/` with `@/Components/`; `@/stores/` with `@/Stores/`
|
||||
|
||||
### In tailwind.config.js
|
||||
|
||||
Please make sure, you've copied template's `tailwind.config.js`. Then replace `content`, to reflect Laravel's structure:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
content: [
|
||||
"./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php",
|
||||
"./storage/framework/views/*.php",
|
||||
"./resources/views/**/*.blade.php",
|
||||
"./resources/js/**/*.vue",
|
||||
"./resources/js/**/*.js",
|
||||
],
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
### In resources/views/app.blade.php
|
||||
|
||||
- Remove `<link rel="stylesheet" href="https://fonts.bunny.net/css2?family=Nunito:wght@400;600;700&display=swap">`
|
||||
|
||||
## Add Pages
|
||||
|
||||
Let's just add first page. You can repeat these steps for other pages, if you wish to.
|
||||
|
||||
First, copy `src/views/HomeView.vue` (from justboil/admin-one-vue-tailwind project) to `resources/js/Pages/` (in your Laravel project).
|
||||
|
||||
Then, open `resources/js/Pages/HomeView.vue` and add `<Head>`:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Head } from "@inertiajs/vue3";
|
||||
// ...
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutAuthenticated>
|
||||
<Head title="Dashboard" />
|
||||
<!-- ... -->
|
||||
</LayoutAuthenticated>
|
||||
</template>
|
||||
```
|
||||
|
||||
Add route in `routes/web.php`. There's a `/dashboard` route already defined by default, so just replace `Inertia::render('Dashboard')` with `Inertia::render('HomeView')`:
|
||||
|
||||
```php
|
||||
Route::get('/dashboard', function () {
|
||||
return Inertia::render('HomeView');
|
||||
})->middleware(['auth', 'verified'])->name('dashboard');
|
||||
```
|
||||
|
||||
## Fix router links
|
||||
|
||||
Here we replace RouterLink with Inertia Link.
|
||||
|
||||
### resources/js/menuAside.js and resources/js/menuNavBar.js
|
||||
|
||||
Optionally, you can pass menu via Inertia shared props, so you'll be able to control it with PHP. Here we'd just use JS.
|
||||
|
||||
`to` should be replaced with `route` which specifies route name defined in `routes/web.php`. For external links `href` should be used instead. Here's an example for `menuAside.js`:
|
||||
|
||||
```javascript
|
||||
export default [
|
||||
"General",
|
||||
[
|
||||
{
|
||||
route: "dashboard",
|
||||
icon: mdiMonitor,
|
||||
label: "Dashboard",
|
||||
},
|
||||
// {
|
||||
// route: "another-route-name",
|
||||
// icon: mdiMonitor,
|
||||
// label: "Dashboard 2",
|
||||
// },
|
||||
{
|
||||
href: "https://example.com/",
|
||||
icon: mdiMonitor,
|
||||
label: "Example.com",
|
||||
},
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
Route names reflect ones defined in `routes/web.php`:
|
||||
|
||||
```php
|
||||
Route::middleware(['auth:sanctum', 'verified'])->get('/dashboard', function () {
|
||||
return Inertia::render('Home');
|
||||
})->name('dashboard');
|
||||
|
||||
// Route::middleware(['auth:sanctum', 'verified'])->get('/dashboard-2', function () {
|
||||
// return Inertia::render('Home2');
|
||||
// })->name('another-route-name');
|
||||
```
|
||||
|
||||
Now, let's update vue files, to make them work with route names and Inertia links.
|
||||
|
||||
### resources/js/components/AsideMenuItem.vue
|
||||
|
||||
Replace `RouterLink` imported from `vue-router` with `Link` import in `<script setup>` and add consts:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Link } from "@inertiajs/vue3";
|
||||
// import { RouterLink } from "vue-router";
|
||||
// ...
|
||||
|
||||
// Add itemHref
|
||||
const itemHref = computed(() =>
|
||||
props.item.route ? route(props.item.route) : props.item.href
|
||||
);
|
||||
|
||||
// Add activeInactiveStyle
|
||||
const activeInactiveStyle = computed(() =>
|
||||
props.item.route && route().current(props.item.route)
|
||||
? styleStore.asideMenuItemActiveStyle
|
||||
: ""
|
||||
);
|
||||
|
||||
// ...
|
||||
</script>
|
||||
```
|
||||
|
||||
In `<template>` section:
|
||||
|
||||
- In `<component>` remove `v-slot` and `:to` attributes; replace `:is` with `:is="item.route ? Link : 'a'"` and `:href` with `:href="itemHref"`
|
||||
- Inside `<component>` replace `:class` attribute for both `<BaseIcon>` components, `<span>` and another `<BaseIcon>` with `:class="activeInactiveStyle"`
|
||||
- ...and for `<span>` (also inside `<component>`) replace `:class` attribute with `:class="[{ 'pr-12': !hasDropdown }, activeInactiveStyle]"`
|
||||
|
||||
### resources/js/components/BaseButton.vue
|
||||
|
||||
Replace `RouterLink` imported from `vue-router` with `Link` import in `<script setup>`:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Link } from "@inertiajs/vue3";
|
||||
// import { RouterLink } from "vue-router";
|
||||
// ...
|
||||
</script>
|
||||
```
|
||||
|
||||
Replace `to` prop declaration with `routeName`:
|
||||
|
||||
```javascript
|
||||
const props = defineProps({
|
||||
// ...
|
||||
routeName: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Fix `const is` declaration, so it returns the `Link` component when `props.routeName` is set:
|
||||
|
||||
```javascript
|
||||
const is = computed(() => {
|
||||
if (props.as) {
|
||||
return props.as;
|
||||
}
|
||||
|
||||
if (props.routeName) {
|
||||
return Link;
|
||||
}
|
||||
|
||||
if (props.href) {
|
||||
return "a";
|
||||
}
|
||||
|
||||
return "button";
|
||||
});
|
||||
```
|
||||
|
||||
Remove `:to` and replace `:href` in `<component>` with `:href="routeName ? route(routeName) : href"`:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<component
|
||||
:is="is"
|
||||
:class="componentClass"
|
||||
:href="routeName ? route(routeName) : href"
|
||||
:type="computedType"
|
||||
:target="target"
|
||||
:disabled="disabled"
|
||||
>
|
||||
<!-- ... -->
|
||||
</component>
|
||||
</template>
|
||||
```
|
||||
|
||||
### resources/js/components/NavBarItem.vue
|
||||
|
||||
Replace `RouterLink` imported from `vue-router` with `Link` import in `<script setup>`:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Link } from "@inertiajs/vue3";
|
||||
// import { RouterLink } from "vue-router";
|
||||
// ...
|
||||
|
||||
// Add itemHref
|
||||
const itemHref = computed(() =>
|
||||
props.item.route ? route(props.item.route) : props.item.href
|
||||
);
|
||||
|
||||
// Update `const is` to return `Link` when `props.routeName` is set:
|
||||
const is = computed(() => {
|
||||
if (props.item.href) {
|
||||
return "a";
|
||||
}
|
||||
|
||||
if (props.item.route) {
|
||||
return Link;
|
||||
}
|
||||
|
||||
return "div";
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
Then, remove `:to` attribute and set `:href` attribute to `:href="itemHref"` in `<component>`.
|
||||
|
||||
## Add Inertia-related stuff
|
||||
|
||||
### resources/js/layouts/LayoutAuthenticated.vue
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
// Remove vue-router stuff:
|
||||
|
||||
// import { useRouter } from 'vue-router'
|
||||
|
||||
// const router = useRouter()
|
||||
|
||||
// router.beforeEach(() => {
|
||||
// isAsideMobileExpanded.value = false
|
||||
// isAsideLgActive.value = false
|
||||
// })
|
||||
|
||||
// Add:
|
||||
|
||||
import { router } from "@inertiajs/vue3";
|
||||
|
||||
router.on("navigate", () => {
|
||||
isAsideMobileExpanded.value = false;
|
||||
isAsideLgActive.value = false;
|
||||
});
|
||||
|
||||
// Replace `isLogout` logic:
|
||||
|
||||
const menuClick = (event, item) => {
|
||||
// ...
|
||||
|
||||
if (item.isLogout) {
|
||||
// Add:
|
||||
router.post(route("logout"));
|
||||
}
|
||||
};
|
||||
|
||||
// ...
|
||||
</script>
|
||||
```
|
||||
|
||||
### resources/js/components/UserAvatarCurrentUser.vue
|
||||
|
||||
Let's fetch user avatar initials based on username stored in database.
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { usePage } from "@inertiajs/vue3";
|
||||
import UserAvatar from "@/components/UserAvatar.vue";
|
||||
|
||||
const userName = computed(() => usePage().props.auth.user.name);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UserAvatar :username="userName" api="initials">
|
||||
<slot />
|
||||
</UserAvatar>
|
||||
</template>
|
||||
```
|
||||
|
||||
### resources/js/components/NavBarItem.vue
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
// Add usePage:
|
||||
import { usePage } from "@inertiajs/vue3";
|
||||
// Remove unused useMainStore:
|
||||
// import { useMainStore } from '@/stores/main.js'
|
||||
// ...
|
||||
|
||||
// Update itemLabel:
|
||||
const itemLabel = computed(() =>
|
||||
props.item.isCurrentUser ? usePage().props.auth.user.name : props.item.label
|
||||
);
|
||||
|
||||
// ...
|
||||
</script>
|
||||
```
|
||||
|
||||
## Upgrading to Premium version
|
||||
|
||||
Please make sure you have completed all previous steps in this guide, so you have everything up and running. Then download and uzip the Premium version files. Next, follow steps described below.
|
||||
|
||||
### Add deps
|
||||
|
||||
```bash
|
||||
npm i @headlessui/vue -D
|
||||
```
|
||||
|
||||
### Copy files
|
||||
|
||||
Copy files to your Laravel project (overwrite free version ones or merge if you have changed something):
|
||||
|
||||
- Copy `src/components/Premium` to `resources/js/components/Premium`
|
||||
- Copy `src/stores` to `resources/js/stores`
|
||||
- Copy `src/config.js` to `resources/js/config.js`
|
||||
- Copy `src/styles.js` to `resources/js/styles.js`
|
||||
- Copy `src/sampleButtonMenuOptions.js` to `resources/js/sampleButtonMenuOptions.js`
|
||||
- Copy `src/colorsPremium.js` to `resources/js/colorsPremium.js`
|
||||
|
||||
### Update tailwind.config.js
|
||||
|
||||
Replace `tailwind.config.js` in your Laravel project with the Premium one. Make sure to preserve `module.exports.content`:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
content: [
|
||||
"./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php",
|
||||
"./storage/framework/views/*.php",
|
||||
"./resources/views/**/*.blade.php",
|
||||
"./resources/js/**/*.vue",
|
||||
"./resources/js/**/*.js",
|
||||
],
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
### Update resources/js/app.js
|
||||
|
||||
Add layout store to `resources/js/app.js`:
|
||||
|
||||
```js
|
||||
// Add layout store
|
||||
import { useLayoutStore } from "@/stores/layout.js";
|
||||
|
||||
const layoutStore = useLayoutStore(pinia);
|
||||
|
||||
layoutStore.responsiveLayoutControl();
|
||||
window.onresize = () => layoutStore.responsiveLayoutControl();
|
||||
```
|
||||
|
||||
### Update resources/js/layouts/LayoutAuthenticated.vue
|
||||
|
||||
Replace contents of `resources/js/layouts/LayoutAuthenticated.vue` with contents of `src/js/layouts/LayoutAuthenticated.vue` (from the Premium version)
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
// Replace router use:
|
||||
|
||||
// import { useRouter } from "vue-router";
|
||||
import { router } from "@inertiajs/vue3";
|
||||
|
||||
// const router = useRouter();
|
||||
|
||||
// router.beforeEach(() => {
|
||||
// layoutStore.isAsideMobileExpanded = false;
|
||||
// });
|
||||
|
||||
router.on("navigate", () => {
|
||||
layoutStore.isAsideMobileExpanded = false;
|
||||
});
|
||||
|
||||
// Add logout:
|
||||
|
||||
const menuClick = (event, item) => {
|
||||
// ...
|
||||
|
||||
if (item.isLogout) {
|
||||
router.post(route("logout"));
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
### Use premium login and signup layouts
|
||||
|
||||
Optionally, you may update layouts of login and signup, located at `resources/js/Pages/Auth` with Premium version layouts from `src/views/Premium/LoginView.vue` and `src/views/Premium/SignupView.vue`
|
||||
|
||||
## Optional steps
|
||||
|
||||
### Default style
|
||||
|
||||
It's likely, you'll use only one app style, either `basic` or one of listed in `src/styles.js`. Follow [this guide](https://justboil.github.io/docs/customization/#default-style) to set one of choice.
|
||||
|
||||
### Fix .editorconfig
|
||||
|
||||
Add to .editorconfig:
|
||||
|
||||
```editorconfig
|
||||
[*.{js,jsx,ts,tsx,vue,html,css}]
|
||||
indent_size = 2
|
||||
```
|
||||
|
||||
### resources/js/bootstrap.js
|
||||
|
||||
Global `lodash` and `axios` aren't needed, as we import them directly when needed. Most likely, you'd not need `axios` at all, as Laravel pushes all data via Inertia.
|
||||
|
||||
## Laravel & Inertia docs
|
||||
|
||||
- [Laravel Docs](https://laravel.com/docs)
|
||||
- [Inertia](https://inertiajs.com/)
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
<script setup>
|
||||
import { useForm, Head } from "@inertiajs/vue3";
|
||||
import { ref } from "vue";
|
||||
import LayoutGuest from "@/layouts/LayoutGuest.vue";
|
||||
import SectionFullScreen from "@/components/SectionFullScreen.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import BaseDivider from "@/components/BaseDivider.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import FormValidationErrors from "@/components/FormValidationErrors.vue";
|
||||
|
||||
const form = useForm({
|
||||
password: "",
|
||||
});
|
||||
|
||||
const passwordInput = ref(null);
|
||||
|
||||
const submit = () => {
|
||||
form.post(route("password.confirm"), {
|
||||
onFinish: () => {
|
||||
form.reset();
|
||||
|
||||
passwordInput.value?.focus();
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutGuest>
|
||||
<Head title="Secure Area" />
|
||||
|
||||
<SectionFullScreen v-slot="{ cardClass }" bg="purplePink">
|
||||
<CardBox :class="cardClass" is-form @submit.prevent="submit">
|
||||
<FormValidationErrors />
|
||||
|
||||
<FormField>
|
||||
<div class="mb-4 text-sm text-gray-600">
|
||||
This is a secure area of the application. Please confirm your
|
||||
password before continuing.
|
||||
</div>
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
label="Password"
|
||||
label-for="password"
|
||||
help="Please enter your password to confirm"
|
||||
>
|
||||
<FormControl
|
||||
id="password"
|
||||
v-model="form.password"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="current-password"
|
||||
@set-ref="passwordInput = $event"
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
|
||||
<BaseButton
|
||||
type="submit"
|
||||
color="info"
|
||||
label="Confirm"
|
||||
:class="{ 'opacity-25': form.processing }"
|
||||
:disabled="form.processing"
|
||||
/>
|
||||
</CardBox>
|
||||
</SectionFullScreen>
|
||||
</LayoutGuest>
|
||||
</template>
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
<script setup>
|
||||
import { useForm, Head, Link } from "@inertiajs/vue3";
|
||||
import { mdiEmail } from "@mdi/js";
|
||||
import LayoutGuest from "@/layouts/LayoutGuest.vue";
|
||||
import SectionFullScreen from "@/components/SectionFullScreen.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import BaseDivider from "@/components/BaseDivider.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import FormValidationErrors from "@/components/FormValidationErrors.vue";
|
||||
import NotificationBarInCard from "@/components/NotificationBarInCard.vue";
|
||||
import BaseLevel from "@/components/BaseLevel.vue";
|
||||
|
||||
defineProps({
|
||||
status: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const form = useForm({
|
||||
email: "",
|
||||
});
|
||||
|
||||
const submit = () => {
|
||||
form.post(route("password.email"));
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutGuest>
|
||||
<Head title="Forgot Password" />
|
||||
|
||||
<SectionFullScreen v-slot="{ cardClass }" bg="purplePink">
|
||||
<CardBox :class="cardClass" is-form @submit.prevent="submit">
|
||||
<FormValidationErrors />
|
||||
|
||||
<NotificationBarInCard v-if="status" color="info">
|
||||
{{ status }}
|
||||
</NotificationBarInCard>
|
||||
|
||||
<FormField>
|
||||
<div class="mb-4 text-sm text-gray-600">
|
||||
Forgot your password? No problem. Just let us know your email
|
||||
address and we will email you a password reset link that will allow
|
||||
you to choose a new one.
|
||||
</div>
|
||||
</FormField>
|
||||
|
||||
<FormField label="Email" help="Please enter your email">
|
||||
<FormControl
|
||||
v-model="form.email"
|
||||
:icon="mdiEmail"
|
||||
autocomplete="email"
|
||||
type="email"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
|
||||
<BaseLevel>
|
||||
<BaseButton
|
||||
type="submit"
|
||||
color="info"
|
||||
label="Email link"
|
||||
:class="{ 'opacity-25': form.processing }"
|
||||
:disabled="form.processing"
|
||||
/>
|
||||
<Link :href="route('login')"> Back to login </Link>
|
||||
</BaseLevel>
|
||||
</CardBox>
|
||||
</SectionFullScreen>
|
||||
</LayoutGuest>
|
||||
</template>
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
<script setup>
|
||||
import { useForm, Head, Link } from "@inertiajs/vue3";
|
||||
import { mdiEmail, mdiFormTextboxPassword } from "@mdi/js";
|
||||
import LayoutGuest from "@/layouts/LayoutGuest.vue";
|
||||
import SectionFullScreen from "@/components/SectionFullScreen.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import BaseDivider from "@/components/BaseDivider.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import FormValidationErrors from "@/components/FormValidationErrors.vue";
|
||||
|
||||
const props = defineProps({
|
||||
email: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
token: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const form = useForm({
|
||||
token: props.token,
|
||||
email: props.email,
|
||||
password: "",
|
||||
password_confirmation: "",
|
||||
});
|
||||
|
||||
const submit = () => {
|
||||
form.post(route("password.update"), {
|
||||
onFinish: () => form.reset("password", "password_confirmation"),
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutGuest>
|
||||
<Head title="Reset Password" />
|
||||
|
||||
<SectionFullScreen v-slot="{ cardClass }" bg="purplePink">
|
||||
<CardBox :class="cardClass" is-form @submit.prevent="submit">
|
||||
<FormValidationErrors />
|
||||
|
||||
<FormField
|
||||
label="Email"
|
||||
label-for="email"
|
||||
help="Please enter your email"
|
||||
>
|
||||
<FormControl
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
:icon="mdiEmail"
|
||||
autocomplete="email"
|
||||
type="email"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
label="Password"
|
||||
label-for="password"
|
||||
help="Please enter new password"
|
||||
>
|
||||
<FormControl
|
||||
id="password"
|
||||
v-model="form.password"
|
||||
:icon="mdiFormTextboxPassword"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
label="Confirm Password"
|
||||
label-for="password_confirmation"
|
||||
help="Please confirm new password"
|
||||
>
|
||||
<FormControl
|
||||
id="password_confirmation"
|
||||
v-model="form.password_confirmation"
|
||||
:icon="mdiFormTextboxPassword"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
|
||||
<BaseButton
|
||||
type="submit"
|
||||
color="info"
|
||||
label="Reset password"
|
||||
:class="{ 'opacity-25': form.processing }"
|
||||
:disabled="form.processing"
|
||||
/>
|
||||
</CardBox>
|
||||
</SectionFullScreen>
|
||||
</LayoutGuest>
|
||||
</template>
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
<script setup>
|
||||
import { useForm, Head } from "@inertiajs/vue3";
|
||||
import { nextTick, ref } from "vue";
|
||||
import LayoutGuest from "@/layouts/LayoutGuest.vue";
|
||||
import SectionFullScreen from "@/components/SectionFullScreen.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import BaseDivider from "@/components/BaseDivider.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import FormValidationErrors from "@/components/FormValidationErrors.vue";
|
||||
import BaseLevel from "@/components/BaseLevel.vue";
|
||||
|
||||
const recovery = ref(false);
|
||||
|
||||
const form = useForm({
|
||||
code: "",
|
||||
recovery_code: "",
|
||||
});
|
||||
|
||||
const recoveryCodeInput = ref(null);
|
||||
const codeInput = ref(null);
|
||||
|
||||
const toggleRecovery = async () => {
|
||||
recovery.value ^= true;
|
||||
|
||||
await nextTick();
|
||||
|
||||
if (recovery.value) {
|
||||
recoveryCodeInput.value?.focus();
|
||||
form.code = "";
|
||||
} else {
|
||||
codeInput.value?.focus();
|
||||
form.recovery_code = "";
|
||||
}
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
form.post(route("two-factor.login"));
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutGuest>
|
||||
<Head title="Two-factor Confirmation" />
|
||||
|
||||
<SectionFullScreen v-slot="{ cardClass }" bg="purplePink">
|
||||
<CardBox :class="cardClass" is-form @submit.prevent="submit">
|
||||
<FormValidationErrors />
|
||||
|
||||
<FormField>
|
||||
<div class="mb-4 text-sm text-gray-600">
|
||||
<template v-if="!recovery">
|
||||
Please confirm access to your account by entering the
|
||||
authentication code provided by your authenticator application.
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
Please confirm access to your account by entering one of your
|
||||
emergency recovery codes.
|
||||
</template>
|
||||
</div>
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
v-if="!recovery"
|
||||
label="Code"
|
||||
label-for="code"
|
||||
help="Please enter one-time code"
|
||||
>
|
||||
<FormControl
|
||||
id="code"
|
||||
v-model="form.code"
|
||||
type="text"
|
||||
inputmode="numeric"
|
||||
autofocus
|
||||
autocomplete="one-time-code"
|
||||
@set-ref="codeInput = $event"
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
v-else
|
||||
label="Recovery Code"
|
||||
label-for="recovery_code"
|
||||
help="Please enter recovery code"
|
||||
>
|
||||
<FormControl
|
||||
id="recovery_code"
|
||||
v-model="form.recovery_code"
|
||||
type="text"
|
||||
class="mt-1 block w-full"
|
||||
autocomplete="one-time-code"
|
||||
@set-ref="recoveryCodeInput = $event"
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
|
||||
<BaseLevel>
|
||||
<BaseButton
|
||||
type="submit"
|
||||
color="info"
|
||||
label="Log in"
|
||||
:class="{ 'opacity-25': form.processing }"
|
||||
:disabled="form.processing"
|
||||
/>
|
||||
<button @click.prevent="toggleRecovery">
|
||||
<template v-if="!recovery"> Use a recovery code </template>
|
||||
|
||||
<template v-else> Use an authentication code </template>
|
||||
</button>
|
||||
</BaseLevel>
|
||||
</CardBox>
|
||||
</SectionFullScreen>
|
||||
</LayoutGuest>
|
||||
</template>
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
<script setup>
|
||||
import { useForm, Head, Link } from "@inertiajs/vue3";
|
||||
import { mdiAccount, mdiAsterisk } from "@mdi/js";
|
||||
import LayoutGuest from "@/layouts/LayoutGuest.vue";
|
||||
import SectionFullScreen from "@/components/SectionFullScreen.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormCheckRadioGroup from "@/components/FormCheckRadioGroup.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import BaseDivider from "@/components/BaseDivider.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseButtons from "@/components/BaseButtons.vue";
|
||||
import FormValidationErrors from "@/components/FormValidationErrors.vue";
|
||||
import NotificationBarInCard from "@/components/NotificationBarInCard.vue";
|
||||
import BaseLevel from "@/components/BaseLevel.vue";
|
||||
|
||||
const props = defineProps({
|
||||
canResetPassword: Boolean,
|
||||
status: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const form = useForm({
|
||||
email: "",
|
||||
password: "",
|
||||
remember: [],
|
||||
});
|
||||
|
||||
const submit = () => {
|
||||
form
|
||||
.transform((data) => ({
|
||||
...data,
|
||||
remember: form.remember && form.remember.length ? "on" : "",
|
||||
}))
|
||||
.post(route("login"), {
|
||||
onFinish: () => form.reset("password"),
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutGuest>
|
||||
<Head title="Login" />
|
||||
|
||||
<SectionFullScreen v-slot="{ cardClass }" bg="purplePink">
|
||||
<CardBox :class="cardClass" is-form @submit.prevent="submit">
|
||||
<FormValidationErrors />
|
||||
|
||||
<NotificationBarInCard v-if="status" color="info">
|
||||
{{ status }}
|
||||
</NotificationBarInCard>
|
||||
|
||||
<FormField
|
||||
label="Email"
|
||||
label-for="email"
|
||||
help="Please enter your email"
|
||||
>
|
||||
<FormControl
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
:icon="mdiAccount"
|
||||
autocomplete="email"
|
||||
type="email"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
label="Password"
|
||||
label-for="password"
|
||||
help="Please enter your password"
|
||||
>
|
||||
<FormControl
|
||||
id="password"
|
||||
v-model="form.password"
|
||||
:icon="mdiAsterisk"
|
||||
type="password"
|
||||
autocomplete="current-password"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormCheckRadioGroup
|
||||
v-model="form.remember"
|
||||
name="remember"
|
||||
:options="{ remember: 'Remember' }"
|
||||
/>
|
||||
|
||||
<BaseDivider />
|
||||
|
||||
<BaseLevel>
|
||||
<BaseButtons>
|
||||
<BaseButton
|
||||
type="submit"
|
||||
color="info"
|
||||
label="Login"
|
||||
:class="{ 'opacity-25': form.processing }"
|
||||
:disabled="form.processing"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="canResetPassword"
|
||||
route-name="password.request"
|
||||
color="info"
|
||||
outline
|
||||
label="Remind"
|
||||
/>
|
||||
</BaseButtons>
|
||||
<Link :href="route('register')"> Register </Link>
|
||||
</BaseLevel>
|
||||
</CardBox>
|
||||
</SectionFullScreen>
|
||||
</LayoutGuest>
|
||||
</template>
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
<script setup>
|
||||
import { useForm, usePage, Head } from "@inertiajs/vue3";
|
||||
import { computed } from "vue";
|
||||
import { mdiAccount, mdiEmail, mdiFormTextboxPassword } from "@mdi/js";
|
||||
import LayoutGuest from "@/layouts/LayoutGuest.vue";
|
||||
import SectionFullScreen from "@/components/SectionFullScreen.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormCheckRadioGroup from "@/components/FormCheckRadioGroup.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import BaseDivider from "@/components/BaseDivider.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseButtons from "@/components/BaseButtons.vue";
|
||||
import FormValidationErrors from "@/components/FormValidationErrors.vue";
|
||||
|
||||
const form = useForm({
|
||||
name: "",
|
||||
email: "",
|
||||
password: "",
|
||||
password_confirmation: "",
|
||||
terms: [],
|
||||
});
|
||||
|
||||
const hasTermsAndPrivacyPolicyFeature = computed(
|
||||
() => usePage().props.jetstream?.hasTermsAndPrivacyPolicyFeature,
|
||||
);
|
||||
|
||||
const submit = () => {
|
||||
form
|
||||
.transform((data) => ({
|
||||
...data,
|
||||
terms: form.terms && form.terms.length,
|
||||
}))
|
||||
.post(route("register"), {
|
||||
onFinish: () => form.reset("password", "password_confirmation"),
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutGuest>
|
||||
<Head title="Register" />
|
||||
|
||||
<SectionFullScreen v-slot="{ cardClass }" bg="purplePink">
|
||||
<CardBox
|
||||
:class="cardClass"
|
||||
class="my-24"
|
||||
is-form
|
||||
@submit.prevent="submit"
|
||||
>
|
||||
<FormValidationErrors />
|
||||
|
||||
<FormField label="Name" label-for="name" help="Please enter your name">
|
||||
<FormControl
|
||||
id="name"
|
||||
v-model="form.name"
|
||||
:icon="mdiAccount"
|
||||
autocomplete="name"
|
||||
type="text"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
label="Email"
|
||||
label-for="email"
|
||||
help="Please enter your email"
|
||||
>
|
||||
<FormControl
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
:icon="mdiEmail"
|
||||
autocomplete="email"
|
||||
type="email"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
label="Password"
|
||||
label-for="password"
|
||||
help="Please enter new password"
|
||||
>
|
||||
<FormControl
|
||||
id="password"
|
||||
v-model="form.password"
|
||||
:icon="mdiFormTextboxPassword"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
label="Confirm Password"
|
||||
label-for="password_confirmation"
|
||||
help="Please confirm your password"
|
||||
>
|
||||
<FormControl
|
||||
id="password_confirmation"
|
||||
v-model="form.password_confirmation"
|
||||
:icon="mdiFormTextboxPassword"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormCheckRadioGroup
|
||||
v-if="hasTermsAndPrivacyPolicyFeature"
|
||||
v-model="form.terms"
|
||||
name="remember"
|
||||
:options="{ agree: 'I agree to the Terms' }"
|
||||
/>
|
||||
|
||||
<BaseDivider />
|
||||
|
||||
<BaseButtons>
|
||||
<BaseButton
|
||||
type="submit"
|
||||
color="info"
|
||||
label="Register"
|
||||
:class="{ 'opacity-25': form.processing }"
|
||||
:disabled="form.processing"
|
||||
/>
|
||||
<BaseButton route-name="login" color="info" outline label="Login" />
|
||||
</BaseButtons>
|
||||
</CardBox>
|
||||
</SectionFullScreen>
|
||||
</LayoutGuest>
|
||||
</template>
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<script setup>
|
||||
import { useForm, Head, Link } from "@inertiajs/vue3";
|
||||
import { computed } from "vue";
|
||||
import LayoutGuest from "@/layouts/LayoutGuest.vue";
|
||||
import SectionFullScreen from "@/components/SectionFullScreen.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import BaseDivider from "@/components/BaseDivider.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import FormValidationErrors from "@/components/FormValidationErrors.vue";
|
||||
import NotificationBarInCard from "@/components/NotificationBarInCard.vue";
|
||||
import BaseLevel from "@/components/BaseLevel.vue";
|
||||
|
||||
const props = defineProps({
|
||||
status: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const form = useForm();
|
||||
|
||||
const verificationLinkSent = computed(
|
||||
() => props.status === "verification-link-sent",
|
||||
);
|
||||
|
||||
const submit = () => {
|
||||
form.post(route("verification.send"));
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutGuest>
|
||||
<Head title="Email Verification" />
|
||||
|
||||
<SectionFullScreen v-slot="{ cardClass }" bg="purplePink">
|
||||
<CardBox :class="cardClass" is-form @submit.prevent="submit">
|
||||
<FormValidationErrors />
|
||||
|
||||
<NotificationBarInCard v-if="verificationLinkSent" color="info">
|
||||
A new verification link has been sent to the email address you
|
||||
provided during registration.
|
||||
</NotificationBarInCard>
|
||||
|
||||
<FormField>
|
||||
<div class="mb-4 text-sm text-gray-600">
|
||||
Thanks for signing up! Before getting started, could you verify your
|
||||
email address by clicking on the link we just emailed to you? If you
|
||||
didn't receive the email, we will gladly send you another.
|
||||
</div>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
|
||||
<BaseLevel>
|
||||
<BaseButton
|
||||
type="submit"
|
||||
color="info"
|
||||
label="Resend Verification Email"
|
||||
:class="{ 'opacity-25': form.processing }"
|
||||
:disabled="form.processing"
|
||||
/>
|
||||
<Link :href="route('logout')" method="post" as="button">
|
||||
Logout
|
||||
</Link>
|
||||
</BaseLevel>
|
||||
</CardBox>
|
||||
</SectionFullScreen>
|
||||
</LayoutGuest>
|
||||
</template>
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
import "../css/_base.css";
|
||||
|
||||
import { createPinia } from "pinia";
|
||||
import { useStyleStore } from "@/stores/style.js";
|
||||
import { darkModeKey, styleKey } from "@/config.js";
|
||||
import { createApp, h } from "vue";
|
||||
import { createInertiaApp } from "@inertiajs/vue3";
|
||||
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";
|
||||
import { ZiggyVue } from "../../vendor/tightenco/ziggy/dist/vue.m";
|
||||
|
||||
const appName =
|
||||
window.document.getElementsByTagName("title")[0]?.innerText || "Laravel";
|
||||
|
||||
const pinia = createPinia();
|
||||
|
||||
createInertiaApp({
|
||||
title: (title) => `${title} - ${appName}`,
|
||||
resolve: (name) =>
|
||||
resolvePageComponent(
|
||||
`./Pages/${name}.vue`,
|
||||
import.meta.glob("./Pages/**/*.vue"),
|
||||
),
|
||||
setup({ el, App, props, plugin }) {
|
||||
return createApp({ render: () => h(App, props) })
|
||||
.use(plugin)
|
||||
.use(pinia)
|
||||
.use(ZiggyVue, Ziggy)
|
||||
.mount(el);
|
||||
},
|
||||
progress: {
|
||||
color: "#4B5563",
|
||||
},
|
||||
});
|
||||
|
||||
const styleStore = useStyleStore(pinia);
|
||||
|
||||
/* App style */
|
||||
styleStore.setStyle(localStorage[styleKey] ?? "basic");
|
||||
|
||||
/* Dark mode */
|
||||
if (
|
||||
(!localStorage[darkModeKey] &&
|
||||
window.matchMedia("(prefers-color-scheme: dark)").matches) ||
|
||||
localStorage[darkModeKey] === "1"
|
||||
) {
|
||||
styleStore.setDarkMode(true);
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { usePage } from "@inertiajs/vue3";
|
||||
import NotificationBarInCard from "@/components/NotificationBarInCard.vue";
|
||||
|
||||
const errors = computed(() => usePage().props.errors);
|
||||
|
||||
const hasErrors = computed(() => Object.keys(errors.value).length > 0);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NotificationBarInCard v-if="hasErrors" color="danger">
|
||||
<b>Whoops! Something went wrong.</b>
|
||||
<span v-for="(error, key) in errors" :key="key">{{ error }}</span>
|
||||
</NotificationBarInCard>
|
||||
</template>
|
||||
|
|
@ -1,235 +0,0 @@
|
|||
# Free Nuxt 3.x Vue 3.x Tailwind 3.x Dashboard
|
||||
|
||||
This guide will help you integrate your Nuxt.js 3.x application with [Admin One - free Vue 3 Tailwind 3 Admin Dashboard with dark mode](https://github.com/justboil/admin-one-vue-tailwind).
|
||||
|
||||
**Please note:** this document is work in progress and Nuxt 3 is in Release Candidate state, so some things can be missing and warnings may occur.
|
||||
|
||||
## Table of contents
|
||||
|
||||
... TOC is coming soon
|
||||
|
||||
## Install Nuxt.js 3.x app with Tailwind CSS
|
||||
|
||||
Check [Nuxt installation guide](https://v3.nuxtjs.org/getting-started/quick-start) for more information.
|
||||
|
||||
* Run `npx nuxi init sample-app`
|
||||
* then `cd sample-app`
|
||||
* and `npm install`
|
||||
|
||||
Then, let's install TailwindCSS. Check [Tailwind Nuxt installation guide](https://tailwindcss.com/docs/guides/nuxtjs) for more information.
|
||||
|
||||
```sh
|
||||
# Install tailwind
|
||||
npm install -D @nuxtjs/tailwindcss @tailwindcss/forms
|
||||
|
||||
# Install other required packages
|
||||
npm i @mdi/js chart.js numeral
|
||||
|
||||
# Install Pinia (official Vuex 5). --legacy-peer-deps is required because of the package dependencies issue
|
||||
npm install --legacy-peer-deps pinia @pinia/nuxt
|
||||
```
|
||||
|
||||
### Copy styles, components and scripts
|
||||
|
||||
Now clone [justboil/admin-one-vue-tailwind](https://github.com/justboil/admin-one-vue-tailwind) project somewhere locally (into any separate folder)
|
||||
|
||||
Next, copy these files **from justboil/admin-one-vue-tailwind project** directory **to nuxt project** directory:
|
||||
|
||||
* Copy `tailwind.config.js` to `/`
|
||||
* Copy `src/components` to `components/`
|
||||
* Copy `src/layouts` to `layouts/`
|
||||
* Copy `src/stores` to `stores/`
|
||||
* Copy `src/colors.js` `src/config.js` `src/menuAside.js` `src/menuNavBar.js` `src/styles.js` to `configs/`
|
||||
* Copy `src/css` to `assets/css/`
|
||||
* Copy `public/favicon.png` to `public/`
|
||||
|
||||
### Prepare items
|
||||
|
||||
#### In nuxt.config.ts
|
||||
|
||||
```javascript
|
||||
import { defineNuxtConfig } from 'nuxt'
|
||||
|
||||
// https://v3.nuxtjs.org/api/configuration/nuxt.config
|
||||
export default defineNuxtConfig({
|
||||
buildModules: [
|
||||
'@pinia/nuxt',
|
||||
],
|
||||
postcss: {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
},
|
||||
css: [
|
||||
'@/assets/css/main.css',
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
#### In tailwind.config.js
|
||||
|
||||
Replace `content`:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
content: [
|
||||
'./composables/**/*.{js,vue,ts}',
|
||||
'./components/**/*.{js,vue,ts}',
|
||||
'./layouts/**/*.vue',
|
||||
'./pages/**/*.vue',
|
||||
'./plugins/**/*.{js,ts}',
|
||||
'app.vue'
|
||||
],
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### In App.vue
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useStyleStore } from '@/stores/style.js'
|
||||
import { darkModeKey, styleKey } from '@/config.js'
|
||||
|
||||
useHead({
|
||||
titleTemplate: (titleChunk) => {
|
||||
const titleBase = 'Admin One Vue 3 Tailwind'
|
||||
|
||||
return titleChunk ? `${titleChunk} - ${titleBase}` : titleBase
|
||||
}
|
||||
})
|
||||
|
||||
const styleStore = useStyleStore()
|
||||
|
||||
const currentStyle = typeof localStorage !== 'undefined' && localStorage[styleKey]
|
||||
? localStorage[styleKey]
|
||||
: 'basic'
|
||||
|
||||
styleStore.setStyle(currentStyle)
|
||||
|
||||
const currentStoredDarkMode = typeof localStorage !== 'undefined' && localStorage[darkModeKey] === '1'
|
||||
|
||||
if ((!currentStoredDarkMode && typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches) || currentStoredDarkMode) {
|
||||
styleStore.setDarkMode(true)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<NuxtLayout>
|
||||
<NuxtPage/>
|
||||
</NuxtLayout>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### In stores/main.js
|
||||
|
||||
Remove `axios`, as you'll likely going to use Nuxt's `useFetch`. Then add some sample data for `clients` and `history`.
|
||||
|
||||
```javascript
|
||||
// import axios from 'axios'
|
||||
|
||||
export const useMainStore = defineStore('main', {
|
||||
state: () => ({
|
||||
// ...
|
||||
|
||||
clients: [
|
||||
{ id: 19, avatar: "https://avatars.dicebear.com/v2/gridy/Howell-Hand.svg", login: "percy64", name: "Howell Hand", company: "Kiehn-Green", city: "Emelyside", progress: 70, created: "Mar 3, 2021" },
|
||||
{ id: 11, avatar: "https://avatars.dicebear.com/v2/gridy/Hope-Howe.svg", login: "dare.concepcion", name: "Hope Howe", company: "Nolan Inc", city: "Paristown", progress: 68, created: "Dec 1, 2021" },
|
||||
{ id: 32, avatar: "https://avatars.dicebear.com/v2/gridy/Nelson-Jerde.svg", login: "geovanni.kessler", name: "Nelson Jerde", company: "Nitzsche LLC", city: "Jailynbury", progress: 49, created: "May 18, 2021"},
|
||||
{ id: 22, avatar: "https://avatars.dicebear.com/v2/gridy/Kim-Weimann.svg", login: "macejkovic.dashawn", name: "Kim Weimann", company: "Brown-Lueilwitz", city: "New Emie", progress: 38, created: "May 4, 2021" }
|
||||
],
|
||||
history: [
|
||||
{ amount: 375.53, name: "Home Loan Account", date: "3 days ago", type: "deposit", business: "Turcotte" },
|
||||
{ amount: 470.26, name: "Savings Account", date: "3 days ago", type: "payment", business: "Murazik - Graham" },
|
||||
{ amount: 971.34, name: "Checking Account", date: "5 days ago", type: "invoice", business: "Fahey - Keebler" },
|
||||
{ amount: 374.63, name: "Auto Loan Account", date: "7 days ago", type: "withdrawal", business: "Collier - Hintz" }
|
||||
]
|
||||
}),
|
||||
actions: {
|
||||
// ...
|
||||
|
||||
fetch (sampleDataKey) {
|
||||
// axios
|
||||
// .get(`data-sources/${sampleDataKey}.json`)
|
||||
// .then(r => {
|
||||
// if (r.data && r.data.data) {
|
||||
// this[sampleDataKey] = r.data.data
|
||||
// }
|
||||
// })
|
||||
// .catch(error => {
|
||||
// alert(error.message)
|
||||
// })
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Rename layouts
|
||||
|
||||
* Rename `layouts/LayoutGuest.vue` to `default.vue`
|
||||
* Rename `layouts/LayoutAuthenticated.vue` to `authenticated.vue`
|
||||
|
||||
## Copy pages
|
||||
|
||||
Let's copy `views/LoginView.vue` with a guest layout and `views/HomeView.vue` with an authenticated layout.
|
||||
|
||||
These pages will then be available under `/` and `/dashboard` url paths.
|
||||
|
||||
#### LoginView.vue
|
||||
|
||||
Copy `views/LoginView.vue` to `pages/index.vue`
|
||||
|
||||
Then, wrap the entire template with `<div>` and replace `<LayoutGuest>` with `<NuxtLayout>`
|
||||
|
||||
**Why we need a div wrapper?** If you use `<NuxtLayout>` within your pages, make sure it is not the root element (or disable layout/page transitions) — [Info](https://v3.nuxtjs.org/guide/directory-structure/layouts#overriding-a-layout-on-a-per-page-basis)
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
// import LayoutGuest from '@/layouts/LayoutGuest.vue'
|
||||
// ...
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<NuxtLayout>
|
||||
<!-- ... -->
|
||||
</NuxtLayout>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### HomeView.vue
|
||||
|
||||
Copy `views/HomeView.vue` to `pages/dashboard.vue`
|
||||
|
||||
Then, wrap the entire template with `<div>` and replace `<LayoutGuest>` with `<NuxtLayout>` with a `name` prop.
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
// import LayoutAuthenticated from '@/layouts/LayoutAuthenticated.vue'
|
||||
// ...
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<NuxtLayout name="authenticated">
|
||||
<!-- ... -->
|
||||
</NuxtLayout>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Replace `<RouterLink>` with `<NuxtLink>`
|
||||
|
||||
Details are coming soon...
|
||||
|
||||
## Remove/update imports
|
||||
|
||||
Nuxt automatically imports any components in your `components/` directory. So, you may safely remove that imports from `<script setup>`. The only exception is for `components/Charts`, so charts import should be left as is.
|
||||
|
||||
## Contributions open
|
||||
|
||||
WIP - work in progress. Some things are missing. Contributions open.
|
||||
|
|
@ -2,20 +2,27 @@ import { defineConfig } from "eslint/config";
|
|||
import js from "@eslint/js";
|
||||
import vue from "eslint-plugin-vue";
|
||||
import prettierConfig from "@vue/eslint-config-prettier";
|
||||
import globalsPkg from "globals";
|
||||
|
||||
const { browser: globalsBrowser, node: globalsNode } = globalsPkg;
|
||||
|
||||
export default defineConfig([
|
||||
js.configs.recommended,
|
||||
|
||||
{
|
||||
files: ["**/*.vue"],
|
||||
plugins: {
|
||||
vue,
|
||||
},
|
||||
files: ["**/*.vue"],
|
||||
languageOptions: {
|
||||
parser: await import("vue-eslint-parser"),
|
||||
parserOptions: {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
},
|
||||
globals: {
|
||||
...globalsBrowser,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
...vue.configs.recommended.rules,
|
||||
|
|
@ -27,7 +34,12 @@ export default defineConfig([
|
|||
languageOptions: {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
globals: {
|
||||
...globalsNode,
|
||||
...globalsBrowser,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
prettierConfig,
|
||||
]);
|
||||
|
|
|
|||
28
package-lock.json
generated
28
package-lock.json
generated
|
|
@ -8,7 +8,7 @@
|
|||
"name": "phaseweb3",
|
||||
"version": "3.0.2",
|
||||
"dependencies": {
|
||||
"@mdi/js": "^7.0.96",
|
||||
"@phosphor-icons/vue": "^2.2.1",
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"@vuepic/vue-datepicker": "^11.0.1",
|
||||
"axios": "^1.11.0",
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
"crypto-js": "^4.2.0",
|
||||
"dotenv": "^17.2.1",
|
||||
"downloadjs": "^1.4.7",
|
||||
"globals": "^16.3.0",
|
||||
"js-cookie": "^3.0.5",
|
||||
"numeral": "^2.0.6",
|
||||
"particles.js": "^2.0.0",
|
||||
|
|
@ -745,10 +746,16 @@
|
|||
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz",
|
||||
"integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w=="
|
||||
},
|
||||
"node_modules/@mdi/js": {
|
||||
"version": "7.4.47",
|
||||
"resolved": "https://registry.npmjs.org/@mdi/js/-/js-7.4.47.tgz",
|
||||
"integrity": "sha512-KPnNOtm5i2pMabqZxpUz7iQf+mfrYZyKCZ8QNz85czgEt7cuHcGorWfdzUMWYA0SD+a6Hn4FmJ+YhzzzjkTZrQ=="
|
||||
"node_modules/@phosphor-icons/vue": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@phosphor-icons/vue/-/vue-2.2.1.tgz",
|
||||
"integrity": "sha512-3RNg1utc2Z5RwPKWFkW3eXI/0BfQAwXgtFxPUPeSzi55jGYUq16b+UqcgbKLazWFlwg5R92OCLKjDiJjeiJcnA==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": ">=3.2.39"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgr/core": {
|
||||
"version": "0.2.9",
|
||||
|
|
@ -2493,6 +2500,17 @@
|
|||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "16.3.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz",
|
||||
"integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-pattern .gitignore"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdi/js": "^7.0.96",
|
||||
"@phosphor-icons/vue": "^2.2.1",
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"@vuepic/vue-datepicker": "^11.0.1",
|
||||
"axios": "^1.11.0",
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
"crypto-js": "^4.2.0",
|
||||
"dotenv": "^17.2.1",
|
||||
"downloadjs": "^1.4.7",
|
||||
"globals": "^16.3.0",
|
||||
"js-cookie": "^3.0.5",
|
||||
"numeral": "^2.0.6",
|
||||
"particles.js": "^2.0.0",
|
||||
|
|
|
|||
|
|
@ -23,5 +23,6 @@
|
|||
"3.0.21": ["- (Admin) Finish admin machine/arcade pages", "- (Major) Finish initial public profile page", "- (Minor) Change table right-click behavior", "- (Admin) Finish admin News pages", "- (Admin) Add search for user via card ID"],
|
||||
"3.0.22": ["- (Major) Finish first implementation of the public profile page", "- (Minor) Clean up dashboard game stat box", "- (Minor) Load profile name in game stat box"],
|
||||
"3.0.23": ["- (Major) Moved to Tailwind V4 (SoftieTechCat)", "- (Major) Updated all dependencies (SoftieTechCat)", "- (Bugfix) Fix bug if user has no read news", "- (Backend) Insane optimization with user loading, data loading, cache parsing. (SoftieTechCat)", "- (Minor) Add new greetings."],
|
||||
"3.0.24": ["- (Bugfix) Fix theme forcing for dark mode", "- (Bugfix) Fix animations across entire app", "- (Bugfix) Fix cursor on login screen easter egg", "- (Minor) Add new greeting"]
|
||||
"3.0.24": ["- (Bugfix) Fix theme forcing for dark mode", "- (Bugfix) Fix animations across entire app", "- (Bugfix) Fix cursor on login screen easter egg", "- (Minor) Add new greeting"],
|
||||
"3.0.25": ["- (Major ++) Move from Material Design Icons to Phosphor Icons. Icons are currently set to their initial picks, but may change (suggest a change!)", "- (Major) Add initial icon animations, start work on icon color standards", "- (Minor) Fix ESlint config"]
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
<script setup>
|
||||
import {
|
||||
mdiTestTube,
|
||||
mdiHomeOutline,
|
||||
mdiNewspaperVariantMultiple,
|
||||
mdiGamepad,
|
||||
mdiCashRegister,
|
||||
mdiHome,
|
||||
} from "@mdi/js";
|
||||
PhTestTube,
|
||||
PhHouseLine,
|
||||
PhNewspaper,
|
||||
PhJoystick,
|
||||
PhCashRegister,
|
||||
PhHouse,
|
||||
} from "@phosphor-icons/vue";
|
||||
import { ref } from "vue";
|
||||
// import { getArea } from "@/constants/area";
|
||||
import BaseLevel from "@/components/BaseLevel.vue";
|
||||
|
|
@ -64,9 +64,9 @@ function getCardStyle(path) {
|
|||
v-if="arcadeData.is_beta"
|
||||
label="Beta Enabled"
|
||||
color="warning"
|
||||
:icon="mdiTestTube"
|
||||
:icon="PhTestTube"
|
||||
/>
|
||||
<PillTag label="Private Arcade" color="info" :icon="mdiHomeOutline" />
|
||||
<PillTag label="Private Arcade" color="info" :icon="PhHouseLine" />
|
||||
</div>
|
||||
|
||||
<hr class="border-t border w-full" />
|
||||
|
|
@ -96,26 +96,26 @@ function getCardStyle(path) {
|
|||
<div class="md:w-full grid grid-cols-1 md:grid-cols-4 gap-3">
|
||||
<BaseButton
|
||||
:href="`/#/arcade/${arcade.id}`"
|
||||
:icon="mdiHome"
|
||||
:icon="PhHouse"
|
||||
color="info"
|
||||
label="Arcade Home"
|
||||
class="w-full md:w-[150px]"
|
||||
/>
|
||||
<BaseButton
|
||||
:href="`/#/arcade/${arcade.id}/events`"
|
||||
:icon="mdiNewspaperVariantMultiple"
|
||||
:icon="PhNewspaper"
|
||||
color="info"
|
||||
label="Event Settings"
|
||||
/>
|
||||
<BaseButton
|
||||
:href="`/#/arcade/${arcade.id}/machines`"
|
||||
:icon="mdiGamepad"
|
||||
:icon="PhJoystick"
|
||||
color="info"
|
||||
label="Machine List"
|
||||
/>
|
||||
<BaseButton
|
||||
:href="`/#/arcade/${arcade.id}/paseli`"
|
||||
:icon="mdiCashRegister"
|
||||
:icon="PhCashRegister"
|
||||
color="info"
|
||||
label="PASELI"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { RouterLink } from "vue-router";
|
|||
import { getButtonColor } from "@/colors.js";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import { useMainStore } from "@/stores/main";
|
||||
import { PhShrimp } from "@phosphor-icons/vue";
|
||||
|
||||
const props = defineProps({
|
||||
label: {
|
||||
|
|
@ -11,7 +12,7 @@ const props = defineProps({
|
|||
default: null,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
iconSize: {
|
||||
|
|
@ -146,7 +147,13 @@ const mainStore = useMainStore();
|
|||
>
|
||||
{{ tooltip }}
|
||||
</div>
|
||||
<BaseIcon v-if="icon" :path="icon" :size="iconSize" />
|
||||
|
||||
<template v-if="mainStore?.userCustomize?.shrimpLinks">
|
||||
<BaseIcon :icon="PhShrimp" :size="iconSize" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<BaseIcon v-if="icon" :icon="icon" :size="iconSize" />
|
||||
</template>
|
||||
<span v-if="label" :class="labelClass">{{
|
||||
mainStore.userCustomize.shrimpLinks ? "Shrimp" : label
|
||||
}}</span>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,13 @@ import { computed } from "vue";
|
|||
const props = defineProps({
|
||||
path: {
|
||||
type: String,
|
||||
required: true,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
icon: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
w: {
|
||||
type: String,
|
||||
|
|
@ -22,6 +28,10 @@ const props = defineProps({
|
|||
type: String,
|
||||
default: "",
|
||||
},
|
||||
fill: {
|
||||
type: String,
|
||||
default: "duotone",
|
||||
},
|
||||
});
|
||||
|
||||
const spanClass = computed(
|
||||
|
|
@ -29,19 +39,24 @@ const spanClass = computed(
|
|||
`inline-flex justify-center items-center ${props.w} ${props.h} ${props.color}`,
|
||||
);
|
||||
|
||||
const iconSize = computed(() => props.size ?? 16);
|
||||
const iconSize = computed(() => props.size ?? (props.icon ? 20 : 18));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span :class="spanClass">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
:width="iconSize"
|
||||
:height="iconSize"
|
||||
class="inline-block"
|
||||
>
|
||||
<path fill="currentColor" :d="path" />
|
||||
</svg>
|
||||
<template v-if="props.path">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
:width="iconSize"
|
||||
:height="iconSize"
|
||||
class="inline-block"
|
||||
>
|
||||
<path fill="currentColor" :d="path" />
|
||||
</svg>
|
||||
</template>
|
||||
<template v-else-if="props.icon">
|
||||
<icon :size="iconSize" :weight="props.fill" />
|
||||
</template>
|
||||
<slot />
|
||||
</span>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,84 +0,0 @@
|
|||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { mdiTrendingDown, mdiTrendingUp, mdiTrendingNeutral } from "@mdi/js";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import BaseLevel from "@/components/BaseLevel.vue";
|
||||
import PillTag from "@/components/PillTag.vue";
|
||||
import UserAvatar from "@/components/UserAvatar.vue";
|
||||
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
login: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
date: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
progress: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const pillType = computed(() => {
|
||||
if (props.type) {
|
||||
return props.type;
|
||||
}
|
||||
|
||||
if (props.progress) {
|
||||
if (props.progress >= 60) {
|
||||
return "success";
|
||||
}
|
||||
if (props.progress >= 40) {
|
||||
return "warning";
|
||||
}
|
||||
|
||||
return "danger";
|
||||
}
|
||||
|
||||
return "info";
|
||||
});
|
||||
|
||||
const pillIcon = computed(() => {
|
||||
return {
|
||||
success: mdiTrendingUp,
|
||||
warning: mdiTrendingNeutral,
|
||||
danger: mdiTrendingDown,
|
||||
info: null,
|
||||
}[pillType.value];
|
||||
});
|
||||
|
||||
const pillText = computed(() => props.text ?? `${props.progress}%`);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CardBox class="mb-2" is-hoverable>
|
||||
<BaseLevel>
|
||||
<BaseLevel type="justify-start md:space-x-4">
|
||||
<UserAvatar class="w-12" :username="name" />
|
||||
<div class="text-center md:text-left overflow-hidden">
|
||||
<h4 class="text-xl text-ellipsis">
|
||||
{{ name }}
|
||||
</h4>
|
||||
<p class="text-gray-500 dark:text-slate-400">
|
||||
{{ date }} @ {{ login }}
|
||||
</p>
|
||||
</div>
|
||||
</BaseLevel>
|
||||
<PillTag :color="pillType" :label="pillText" :icon="pillIcon" />
|
||||
</BaseLevel>
|
||||
</CardBox>
|
||||
</template>
|
||||
|
|
@ -7,11 +7,11 @@ defineProps({
|
|||
required: true,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
buttonIcon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
|
@ -31,7 +31,7 @@ const buttonClick = (event) => {
|
|||
class="flex items-center py-3 grow font-bold"
|
||||
:class="[icon ? 'px-4' : 'px-6']"
|
||||
>
|
||||
<BaseIcon v-if="icon" :path="icon" class="mr-3" />
|
||||
<BaseIcon v-if="icon" :icon="icon" class="mr-3" />
|
||||
{{ title }}
|
||||
</div>
|
||||
<button
|
||||
|
|
@ -39,7 +39,7 @@ const buttonClick = (event) => {
|
|||
class="flex items-center p-2 justify-center ring-blue-700 focus:ring"
|
||||
@click="buttonClick"
|
||||
>
|
||||
<BaseIcon :path="buttonIcon" />
|
||||
<BaseIcon :icon="buttonIcon" />
|
||||
</button>
|
||||
</header>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ defineProps({
|
|||
default: 0,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
prefix: {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import axios from "axios";
|
||||
import { watch, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { mdiLoading } from "@mdi/js";
|
||||
import { PhSpinnerBall } from "@phosphor-icons/vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -126,7 +126,7 @@ function revert() {
|
|||
/>
|
||||
<BaseIcon
|
||||
v-if="loading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import axios from "axios";
|
||||
import { watch, ref, reactive } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { mdiLoading } from "@mdi/js";
|
||||
import { PhSpinnerBall } from "@phosphor-icons/vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -173,7 +173,7 @@ function revertEmblem() {
|
|||
/>
|
||||
<BaseIcon
|
||||
v-if="loading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
import { ref, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import {
|
||||
mdiHome,
|
||||
mdiCog,
|
||||
mdiAccountDetails,
|
||||
mdiPlaylistMusicOutline,
|
||||
mdiSwordCross,
|
||||
mdiFormatListText,
|
||||
} from "@mdi/js";
|
||||
PhHouse,
|
||||
PhGear,
|
||||
PhUserList,
|
||||
PhPlaylist,
|
||||
PhSword,
|
||||
PhListStar,
|
||||
} from "@phosphor-icons/vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import GameTitleLine from "@/components/GameTitleLine.vue";
|
||||
import { getVideoSource, getCardStyle } from "@/constants/sources";
|
||||
|
|
@ -41,7 +41,7 @@ function loadRoutes() {
|
|||
label: `${
|
||||
props.game.shortName ? props.game.shortName : props.game.name
|
||||
} Home`,
|
||||
icon: mdiHome,
|
||||
icon: PhHouse,
|
||||
path: `/#/games/${props.game.id}/`,
|
||||
route: "game_page",
|
||||
color: "success",
|
||||
|
|
@ -51,7 +51,7 @@ function loadRoutes() {
|
|||
if (userProfiles.value.some((profile) => profile.game === props.game.id)) {
|
||||
navigationData.push({
|
||||
label: "My Profile",
|
||||
icon: mdiAccountDetails,
|
||||
icon: PhUserList,
|
||||
path: `/#/games/${props.game.id}/profiles/${mainStore.userId}`,
|
||||
route: "game_profile",
|
||||
color: "info",
|
||||
|
|
@ -59,7 +59,7 @@ function loadRoutes() {
|
|||
|
||||
navigationData.push({
|
||||
label: "Edit Profile",
|
||||
icon: mdiCog,
|
||||
icon: PhGear,
|
||||
path: `/#/games/${props.game.id}/edit`,
|
||||
route: "edit_profile",
|
||||
color: "warning",
|
||||
|
|
@ -68,7 +68,7 @@ function loadRoutes() {
|
|||
if (!props.game.noRivals) {
|
||||
navigationData.push({
|
||||
label: "Rivals",
|
||||
icon: mdiSwordCross,
|
||||
icon: PhSword,
|
||||
path: `/#/games/${props.game.id}/rivals`,
|
||||
route: "game_rivals",
|
||||
color: "danger",
|
||||
|
|
@ -78,7 +78,7 @@ function loadRoutes() {
|
|||
if (!props.game.noScores) {
|
||||
navigationData.push({
|
||||
label: "My Scores",
|
||||
icon: mdiPlaylistMusicOutline,
|
||||
icon: PhPlaylist,
|
||||
path: `/#/games/${props.game.id}/scores/${mainStore.userId}`,
|
||||
color: "info",
|
||||
});
|
||||
|
|
@ -86,7 +86,7 @@ function loadRoutes() {
|
|||
|
||||
navigationData.push({
|
||||
label: "My Records",
|
||||
icon: mdiFormatListText,
|
||||
icon: PhListStar,
|
||||
path: `/#/games/${props.game.id}/records/${mainStore.userId}`,
|
||||
route: "personal_records",
|
||||
color: "success",
|
||||
|
|
@ -97,14 +97,14 @@ function loadRoutes() {
|
|||
navigationData.push(
|
||||
{
|
||||
label: "Network Scores",
|
||||
icon: mdiPlaylistMusicOutline,
|
||||
icon: PhPlaylist,
|
||||
path: `/#/games/${props.game.id}/scores`,
|
||||
route: "all_scores",
|
||||
color: "info",
|
||||
},
|
||||
{
|
||||
label: "Network Records",
|
||||
icon: mdiFormatListText,
|
||||
icon: PhListStar,
|
||||
path: `/#/games/${props.game.id}/records`,
|
||||
route: "all_records",
|
||||
color: "success",
|
||||
|
|
@ -133,11 +133,11 @@ function loadRoutes() {
|
|||
<div class="bg-white dark:bg-slate-900/90 rounded-2xl card-content">
|
||||
<GameTitleLine :path="game.icon" :title="game.name">
|
||||
<div class="w-full">
|
||||
<div class="w-full">
|
||||
<div class="w-full mb-4">
|
||||
<slot />
|
||||
</div>
|
||||
<div
|
||||
class="w-full grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:flex gap-3"
|
||||
class="w-full grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-6 2xl:flex gap-3"
|
||||
>
|
||||
<template v-for="item of loadRoutes()" :key="item.path">
|
||||
<BaseButton
|
||||
|
|
|
|||
|
|
@ -1,16 +1,8 @@
|
|||
<script setup>
|
||||
import axios from "axios";
|
||||
import {
|
||||
mdiCog,
|
||||
mdiAccountDetails,
|
||||
mdiPlaylistMusicOutline,
|
||||
mdiFormatListText,
|
||||
mdiAxeBattle,
|
||||
} from "@mdi/js";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { dashCode } from "@/constants/userData";
|
||||
import { GameConstants, getGameInfo, getRivalInfo } from "@/constants";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import { GameConstants, getGameInfo } from "@/constants";
|
||||
import UserEmblem from "@/components/UserEmblem.vue";
|
||||
import UserQpro from "@/components/UserQpro.vue";
|
||||
import { getGitadoraColor, getJubilityColor } from "@/constants/skillColor.js";
|
||||
|
|
@ -28,10 +20,6 @@ const props = defineProps({
|
|||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
useSmall: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
function colorText() {
|
||||
|
|
@ -112,68 +100,6 @@ onMounted(async () => {
|
|||
<p class="text-xl font-mono">{{ dashCode(profile.extid) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2 text-center md:text-left lg:mx-12 p-2">
|
||||
<div
|
||||
class="pt-6 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-5 gap-3"
|
||||
>
|
||||
<BaseButton
|
||||
v-if="!useSmall && game"
|
||||
:icon="mdiAccountDetails"
|
||||
:href="`/#/games/${game}/profiles/${profile.userId}`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
label="View Profile"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="!useSmall && game"
|
||||
:icon="mdiCog"
|
||||
:href="`/#/games/${game}/edit`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
label="Edit Profile"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="!useSmall && game && getRivalInfo(game, version)"
|
||||
:icon="mdiAxeBattle"
|
||||
:href="`/#/games/${game}/rivals`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
label="Rivals"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="!useSmall && !thisGame.noScores"
|
||||
:href="`/#/games/${game}/scores/${profile.userId}`"
|
||||
:icon="mdiPlaylistMusicOutline"
|
||||
:outline="false"
|
||||
color="info"
|
||||
label="My Scores"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="!useSmall && !thisGame.noRecords"
|
||||
:href="`/#/games/${game}/records/${profile.userId}`"
|
||||
:icon="mdiFormatListText"
|
||||
:outline="false"
|
||||
color="info"
|
||||
label="My Records"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="!useSmall && !thisGame.noScores"
|
||||
:href="`/#/games/${game}/scores`"
|
||||
:icon="mdiPlaylistMusicOutline"
|
||||
:outline="false"
|
||||
color="info"
|
||||
label="Network Scores"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="!useSmall && !thisGame.noRecords"
|
||||
:href="`/#/games/${game}/records`"
|
||||
:icon="mdiFormatListText"
|
||||
:outline="false"
|
||||
color="info"
|
||||
label="Network Records"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<slot />
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import axios from "axios";
|
||||
import { watch, ref, reactive } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { mdiLoading } from "@mdi/js";
|
||||
import { PhSpinnerBall } from "@phosphor-icons/vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -160,7 +160,7 @@ function revert() {
|
|||
/>
|
||||
<BaseIcon
|
||||
v-if="loading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import axios from "axios";
|
||||
import { watch, ref, reactive } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { mdiLoading, mdiChevronDown, mdiChevronUp } from "@mdi/js";
|
||||
import { PhSpinnerBall, PhCaretDown, PhCaretUp } from "@phosphor-icons/vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -170,7 +170,7 @@ function toggleStickerCollapse(index) {
|
|||
<div class="flex justify-between items-center">
|
||||
<span class="text-lg">Sticker {{ index + 1 }}</span>
|
||||
<BaseButton
|
||||
:icon="collapsedStickers[index] ? mdiChevronDown : mdiChevronUp"
|
||||
:icon="collapsedStickers[index] ? PhCaretDown : PhCaretUp"
|
||||
color="info"
|
||||
@click="toggleStickerCollapse(index)"
|
||||
/>
|
||||
|
|
@ -264,7 +264,7 @@ function toggleStickerCollapse(index) {
|
|||
/>
|
||||
<BaseIcon
|
||||
v-if="loading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { containerMaxW } from "@/config.js";
|
||||
import { mdiCash, mdiGithub } from "@mdi/js";
|
||||
import { PhPaypalLogo, PhGithubLogo } from "@phosphor-icons/vue";
|
||||
import BaseLevel from "@/components/BaseLevel.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ const appVersion = import.meta.env.VITE_APP_VERSION;
|
|||
color="warning"
|
||||
href="https://paypal.me/trmazi"
|
||||
label="Donate"
|
||||
:icon="mdiCash"
|
||||
:icon="PhPaypalLogo"
|
||||
icon-size="24"
|
||||
/>
|
||||
<BaseButton
|
||||
|
|
@ -37,7 +37,7 @@ const appVersion = import.meta.env.VITE_APP_VERSION;
|
|||
href="https://github.com/PhaseII-eAmusement-Network/PhaseWeb3-Vue"
|
||||
target="_blank"
|
||||
label="View on GitHub"
|
||||
:icon="mdiGithub"
|
||||
:icon="PhGithubLogo"
|
||||
icon-size="24"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ const props = defineProps({
|
|||
default: null,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
options: {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import BaseIcon from "@/components/BaseIcon.vue";
|
|||
|
||||
defineProps({
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
h: {
|
||||
|
|
@ -15,7 +15,7 @@ defineProps({
|
|||
|
||||
<template>
|
||||
<BaseIcon
|
||||
:path="icon"
|
||||
:icon="icon"
|
||||
w="w-10"
|
||||
:h="h"
|
||||
class="absolute top-0 left-0 z-10 pointer-events-none text-gray-500 dark:text-slate-400"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { mdiUpload } from "@mdi/js";
|
||||
import { PhUpload } from "@phosphor-icons/vue";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
|
||||
|
|
@ -13,8 +13,8 @@ const props = defineProps({
|
|||
default: null,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: mdiUpload,
|
||||
type: Object,
|
||||
default: PhUpload,
|
||||
},
|
||||
accept: {
|
||||
type: String,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { mdiDownload, mdiChevronLeft, mdiChevronRight } from "@mdi/js";
|
||||
import { PhDownload, PhCaretLeft, PhCaretRight } from "@phosphor-icons/vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import UserAvatar from "@/components/UserAvatar.vue";
|
||||
import DownloadJS from "downloadjs";
|
||||
|
|
@ -60,7 +60,7 @@ function downloadJSON() {
|
|||
>
|
||||
<div class="flex items-center">
|
||||
<BaseButton
|
||||
:icon="mdiChevronLeft"
|
||||
:icon="PhCaretLeft"
|
||||
color="info"
|
||||
very-small
|
||||
:disabled="isFirstPage"
|
||||
|
|
@ -70,7 +70,7 @@ function downloadJSON() {
|
|||
currentPaginationNumber
|
||||
}}</span>
|
||||
<BaseButton
|
||||
:icon="mdiChevronRight"
|
||||
:icon="PhCaretRight"
|
||||
color="info"
|
||||
very-small
|
||||
small
|
||||
|
|
@ -101,7 +101,7 @@ function downloadJSON() {
|
|||
<div class="p-2 w-full flex md:justify-end">
|
||||
<BaseButton
|
||||
label="Export Table"
|
||||
:icon="mdiDownload"
|
||||
:icon="PhDownload"
|
||||
color="info"
|
||||
@click="downloadJSON"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import BaseIcon from "@/components/BaseIcon.vue";
|
|||
|
||||
const props = defineProps({
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
iconColor: {
|
||||
|
|
@ -34,7 +34,7 @@ const spanColor = computed(() => props.iconColor);
|
|||
|
||||
<template>
|
||||
<BaseIcon
|
||||
:path="icon"
|
||||
:icon="icon"
|
||||
:w="w"
|
||||
:h="h"
|
||||
:color="spanColor"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { ref, computed } from "vue";
|
||||
import { RouterLink } from "vue-router";
|
||||
import { useStyleStore } from "@/stores/style.js";
|
||||
import { mdiMinus, mdiPlus } from "@mdi/js";
|
||||
import { PhCaretUp } from "@phosphor-icons/vue";
|
||||
import { getButtonColor } from "@/colors.js";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import AsideMenuList from "@/components/Menus/AsideMenuList.vue";
|
||||
|
|
@ -59,7 +59,8 @@ const menuClick = (event) => {
|
|||
>
|
||||
<BaseIcon
|
||||
v-if="item.icon"
|
||||
:path="item.icon"
|
||||
:icon="item.icon"
|
||||
:fill="item.fill ? item.fill : 'regular'"
|
||||
class="flex-none"
|
||||
:class="[vSlot && vSlot.isExactActive ? asideMenuItemActiveStyle : '']"
|
||||
w="w-16"
|
||||
|
|
@ -75,10 +76,15 @@ const menuClick = (event) => {
|
|||
>
|
||||
<BaseIcon
|
||||
v-if="hasDropdown"
|
||||
:path="isDropdownActive ? mdiMinus : mdiPlus"
|
||||
class="flex-none"
|
||||
:class="[vSlot && vSlot.isExactActive ? asideMenuItemActiveStyle : '']"
|
||||
w="w-12"
|
||||
:icon="PhCaretUp"
|
||||
:size="18"
|
||||
:fill="item.fill ? item.fill : 'regular'"
|
||||
class="flex-none transition-transform duration-150 ease-in-out"
|
||||
:class="[
|
||||
isDropdownActive ? 'rotate-0' : 'rotate-180',
|
||||
vSlot && vSlot.isExactActive ? asideMenuItemActiveStyle : '',
|
||||
]"
|
||||
w="w-10"
|
||||
/>
|
||||
</component>
|
||||
<Transition
|
||||
|
|
@ -92,10 +98,7 @@ const menuClick = (event) => {
|
|||
<AsideMenuList
|
||||
v-show="isDropdownActive"
|
||||
:menu="item.menu"
|
||||
:class="[
|
||||
styleStore.asideMenuDropdownStyle,
|
||||
'dark:bg-slate-800/50',
|
||||
]"
|
||||
:class="[styleStore.asideMenuDropdownStyle, 'dark:bg-slate-800/50']"
|
||||
is-dropdown-list
|
||||
/>
|
||||
</Transition>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { mdiLogout, mdiClose } from "@mdi/js";
|
||||
import { PhSignOut, PhXCircle } from "@phosphor-icons/vue";
|
||||
import { computed } from "vue";
|
||||
import { useStyleStore } from "@/stores/style.js";
|
||||
import AsideMenuList from "@/components/Menus/AsideMenuList.vue";
|
||||
|
|
@ -18,14 +18,15 @@ const styleStore = useStyleStore();
|
|||
|
||||
const logoutItem = computed(() => ({
|
||||
label: "Log out",
|
||||
icon: mdiLogout,
|
||||
icon: PhSignOut,
|
||||
color: "info",
|
||||
isLogout: true,
|
||||
fill: "regular",
|
||||
}));
|
||||
|
||||
const closeItem = computed(() => ({
|
||||
label: "Close",
|
||||
icon: mdiClose,
|
||||
icon: PhXCircle,
|
||||
color: "danger",
|
||||
}));
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ defineProps({
|
|||
isDropdownList: Boolean,
|
||||
menu: {
|
||||
type: Array,
|
||||
required: true,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import { PhXSquare } from "@phosphor-icons/vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseButtons from "@/components/BaseButtons.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -60,7 +60,7 @@ window.addEventListener("keydown", (e) => {
|
|||
<CardBoxComponentTitle :title="title">
|
||||
<BaseButton
|
||||
v-if="hasCancel"
|
||||
:icon="mdiClose"
|
||||
:icon="PhXSquare"
|
||||
color="whiteDark"
|
||||
small
|
||||
rounded-full
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import CardBox from "@/components/CardBox.vue";
|
|||
import OverlayLayer from "@/components/OverlayLayer.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import { mdiEmailAlertOutline } from "@mdi/js";
|
||||
import { PhEnvelopeOpen } from "@phosphor-icons/vue";
|
||||
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
import { loadCookie, saveCookie } from "@/stores/cookies";
|
||||
|
|
@ -47,7 +47,7 @@ function verifyLater() {
|
|||
<div class="grid text-center justify-center grid-cols-1 gap-3">
|
||||
<div class="place-self-center">
|
||||
<BaseIcon
|
||||
:path="mdiEmailAlertOutline"
|
||||
:icon="PhEnvelopeOpen"
|
||||
class="text-yellow-600"
|
||||
w="w-20"
|
||||
:size="45"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import CardBox from "@/components/CardBox.vue";
|
|||
import OverlayLayer from "@/components/OverlayLayer.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import { mdiCheckOutline, mdiCloseOutline } from "@mdi/js";
|
||||
import { PhCloudCheck, PhCloudX } from "@phosphor-icons/vue";
|
||||
|
||||
const $router = useRouter();
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ function hotReload() {
|
|||
>
|
||||
<div class="place-self-center">
|
||||
<BaseIcon
|
||||
:path="mdiCheckOutline"
|
||||
:icon="PhCloudCheck"
|
||||
class="text-green-700"
|
||||
w="w-20"
|
||||
:size="45"
|
||||
|
|
@ -73,12 +73,7 @@ function hotReload() {
|
|||
class="grid text-center justify-center grid-cols-1 gap-3"
|
||||
>
|
||||
<div class="place-self-center">
|
||||
<BaseIcon
|
||||
:path="mdiCloseOutline"
|
||||
class="text-red-500"
|
||||
w="w-20"
|
||||
:size="45"
|
||||
/>
|
||||
<BaseIcon :icon="PhCloudX" class="text-red-500" w="w-20" :size="45" />
|
||||
</div>
|
||||
<h1 class="text-xl md:text-2xl">Uh Oh!</h1>
|
||||
<h1 class="text-lg md:text-xl">
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import CardBox from "@/components/CardBox.vue";
|
|||
import OverlayLayer from "@/components/OverlayLayer.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import { mdiSourceBranchRefresh } from "@mdi/js";
|
||||
import { PhSparkle } from "@phosphor-icons/vue";
|
||||
import { APIUserAppUpdate, APIUserCustomize } from "@/stores/api/account";
|
||||
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
|
|
@ -80,7 +80,7 @@ async function updateUserData(disable = false) {
|
|||
<div class="grid text-center justify-center grid-cols-1 gap-3">
|
||||
<div class="place-self-center">
|
||||
<BaseIcon
|
||||
:path="mdiSourceBranchRefresh"
|
||||
:icon="PhSparkle"
|
||||
class="text-emerald-600"
|
||||
w="w-20"
|
||||
:size="45"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { mdiClose, mdiDotsVertical } from "@mdi/js";
|
||||
import { PhCaretDoubleUp } from "@phosphor-icons/vue";
|
||||
import { containerMaxW } from "@/config.js";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import NavBarMenuList from "@/components/NavBarMenuList.vue";
|
||||
|
|
@ -35,8 +35,11 @@ const isMenuNavBarActive = ref(false);
|
|||
@click.prevent="isMenuNavBarActive = !isMenuNavBarActive"
|
||||
>
|
||||
<BaseIcon
|
||||
:path="isMenuNavBarActive ? mdiClose : mdiDotsVertical"
|
||||
size="24"
|
||||
:icon="PhCaretDoubleUp"
|
||||
:size="24"
|
||||
fill="bold"
|
||||
class="flex-none transition-transform duration-150 ease-in-out"
|
||||
:class="[isMenuNavBarActive ? 'rotate-0' : 'rotate-180']"
|
||||
/>
|
||||
</NavBarItemPlain>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { mdiChevronUp, mdiChevronDown } from "@mdi/js";
|
||||
import { PhCaretUp } from "@phosphor-icons/vue";
|
||||
import { RouterLink } from "vue-router";
|
||||
import { computed, ref, onMounted, onBeforeUnmount } from "vue";
|
||||
import { useStyleStore } from "@/stores/style.js";
|
||||
|
|
@ -110,7 +110,12 @@ onBeforeUnmount(() => {
|
|||
v-if="item.isCurrentUser"
|
||||
class="w-6 h-6 mr-3 inline-flex"
|
||||
/>
|
||||
<BaseIcon v-if="item.icon" :path="item.icon" class="transition-colors" />
|
||||
<BaseIcon
|
||||
v-if="item.icon"
|
||||
:icon="item.icon"
|
||||
:fill="item.fill ?? 'duotone'"
|
||||
class="transition-colors"
|
||||
/>
|
||||
<span
|
||||
class="px-2 transition-colors"
|
||||
:class="{ 'lg:hidden': item.isDesktopNoLabel && item.icon }"
|
||||
|
|
@ -118,8 +123,11 @@ onBeforeUnmount(() => {
|
|||
>
|
||||
<BaseIcon
|
||||
v-if="item.menu"
|
||||
:path="isDropdownActive ? mdiChevronUp : mdiChevronDown"
|
||||
class="hidden lg:inline-flex transition-colors"
|
||||
:icon="PhCaretUp"
|
||||
:size="18"
|
||||
fill="regular"
|
||||
class="flex-none transition-transform duration-150 ease-in-out invisible lg:visible"
|
||||
:class="[isDropdownActive ? 'rotate-0' : 'rotate-180']"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { ref, computed, useSlots } from "vue";
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import { PhX } from "@phosphor-icons/vue";
|
||||
import { colorsBgLight, colorsOutline } from "@/colors.js";
|
||||
import BaseLevel from "@/components/BaseLevel.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
|
|
@ -8,7 +8,7 @@ import BaseButton from "@/components/BaseButton.vue";
|
|||
|
||||
const props = defineProps({
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
outline: {
|
||||
|
|
@ -46,7 +46,7 @@ const hasRightSlot = computed(() => slots.right);
|
|||
<div class="flex flex-col md:flex-row items-center">
|
||||
<BaseIcon
|
||||
v-if="icon"
|
||||
:path="icon"
|
||||
:icon="icon"
|
||||
w="w-10 md:w-5"
|
||||
h="h-10 md:h-5"
|
||||
size="24"
|
||||
|
|
@ -57,7 +57,7 @@ const hasRightSlot = computed(() => slots.right);
|
|||
<slot v-if="hasRightSlot" name="right" />
|
||||
<BaseButton
|
||||
v-else
|
||||
:icon="mdiClose"
|
||||
:icon="PhX"
|
||||
small
|
||||
rounded-full
|
||||
color="white"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ const props = defineProps({
|
|||
required: true,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
small: Boolean,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ defineProps({
|
|||
required: true,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
small: Boolean,
|
||||
|
|
@ -21,7 +21,7 @@ defineProps({
|
|||
>
|
||||
<BaseIcon
|
||||
v-if="icon"
|
||||
:path="icon"
|
||||
:icon="icon"
|
||||
h="h-4"
|
||||
w="w-4"
|
||||
:class="small ? 'mr-1' : 'mr-2'"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { mdiChevronUp, mdiChevronDown, mdiAlertCircleOutline } from "@mdi/js";
|
||||
import { PhCaretUp, PhCaretDown, PhWarningCircle } from "@phosphor-icons/vue";
|
||||
import PillTag from "@/components/PillTag.vue";
|
||||
|
||||
const props = defineProps({
|
||||
|
|
@ -18,21 +18,21 @@ const props = defineProps({
|
|||
const trendStyle = computed(() => {
|
||||
if (props.trendType === "up") {
|
||||
return {
|
||||
icon: mdiChevronUp,
|
||||
icon: PhCaretUp,
|
||||
style: "success",
|
||||
};
|
||||
}
|
||||
|
||||
if (props.trendType === "down") {
|
||||
return {
|
||||
icon: mdiChevronDown,
|
||||
icon: PhCaretDown,
|
||||
style: "danger",
|
||||
};
|
||||
}
|
||||
|
||||
if (props.trendType === "alert") {
|
||||
return {
|
||||
icon: mdiAlertCircleOutline,
|
||||
icon: PhWarningCircle,
|
||||
style: "warning",
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import IconRounded from "@/components/IconRounded.vue";
|
|||
|
||||
defineProps({
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
color: {
|
||||
|
|
@ -38,7 +38,7 @@ const hasSlot = computed(() => useSlots().default);
|
|||
/>
|
||||
<BaseIcon
|
||||
v-else-if="icon"
|
||||
:path="icon"
|
||||
:icon="icon"
|
||||
:color="color"
|
||||
class="mr-2"
|
||||
size="20"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { mdiCog } from "@mdi/js";
|
||||
import { PhGear } from "@phosphor-icons/vue";
|
||||
import { useSlots, computed } from "vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
|
|
@ -7,7 +7,7 @@ import IconRounded from "@/components/IconRounded.vue";
|
|||
|
||||
defineProps({
|
||||
icon: {
|
||||
type: String,
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
title: {
|
||||
|
|
@ -33,12 +33,12 @@ const hasSlot = computed(() => useSlots().default);
|
|||
class="mr-3"
|
||||
bg
|
||||
/>
|
||||
<BaseIcon v-else-if="icon" :path="icon" class="mr-2" size="20" />
|
||||
<BaseIcon v-else-if="icon" :icon="icon" class="mr-2" size="20" />
|
||||
<h1 :class="main ? 'text-3xl' : 'text-2xl'" class="leading-tight">
|
||||
{{ title }}
|
||||
</h1>
|
||||
</div>
|
||||
<slot v-if="hasSlot" />
|
||||
<BaseButton v-else :icon="mdiCog" color="whiteDark" />
|
||||
<BaseButton v-else :icon="PhGear" color="whiteDark" />
|
||||
</section>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -3,21 +3,21 @@ import { ref } from "vue";
|
|||
import { useMainStore } from "@/stores/main";
|
||||
import { RoleConstants } from "@/constants/discordRoles";
|
||||
import {
|
||||
mdiSecurity,
|
||||
mdiTestTube,
|
||||
mdiAccountStar,
|
||||
mdiAccountOff,
|
||||
mdiFlowerPoppy,
|
||||
mdiSharkFinOutline,
|
||||
mdiHandCoinOutline,
|
||||
mdiAccountTieHat,
|
||||
mdiAccountTie,
|
||||
mdiHeartMultipleOutline,
|
||||
mdiCheckDecagramOutline,
|
||||
mdiLinkBoxVariantOutline,
|
||||
mdiAccountCheck,
|
||||
mdiGavel,
|
||||
} from "@mdi/js";
|
||||
PhCrown,
|
||||
PhTestTube,
|
||||
PhShieldStar,
|
||||
PhEyeSlash,
|
||||
PhFlower,
|
||||
PhFish,
|
||||
PhHandCoins,
|
||||
PhShieldChevron,
|
||||
PhBracketsCurly,
|
||||
PhHandHeart,
|
||||
PhSealCheck,
|
||||
PhShrimp,
|
||||
PhUserCheck,
|
||||
PhGavel,
|
||||
} from "@phosphor-icons/vue";
|
||||
import BaseLevel from "@/components/BaseLevel.vue";
|
||||
import UserAvatar from "@/components/UserAvatar.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -151,105 +151,100 @@ function getCardStyle() {
|
|||
v-if="cardData.userAdmin"
|
||||
label="System Admin"
|
||||
color="danger"
|
||||
:icon="mdiSecurity"
|
||||
:icon="PhCrown"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.userBanned"
|
||||
label="Banned"
|
||||
color="danger"
|
||||
:icon="mdiGavel"
|
||||
:icon="PhGavel"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.userId < 300"
|
||||
label="Veteran"
|
||||
color="success"
|
||||
:icon="mdiAccountStar"
|
||||
:icon="PhShieldStar"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="!cardData.userPublic"
|
||||
label="Private Profile"
|
||||
color="info"
|
||||
:icon="mdiAccountOff"
|
||||
:icon="PhEyeSlash"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.userPublic"
|
||||
label="Public Profile"
|
||||
color="success"
|
||||
:icon="mdiAccountCheck"
|
||||
:icon="PhUserCheck"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.discordRoles?.includes(RoleConstants.PLAYER)"
|
||||
label="Verified"
|
||||
color="success"
|
||||
:icon="mdiCheckDecagramOutline"
|
||||
:icon="PhSealCheck"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.discordRoles?.includes(RoleConstants.JACKASS)"
|
||||
label="Jackass"
|
||||
color="slight_danger"
|
||||
:icon="mdiHeartMultipleOutline"
|
||||
:icon="PhHandHeart"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.discordRoles?.includes(RoleConstants.DEVELOPER)"
|
||||
label="Developer"
|
||||
color="success"
|
||||
:icon="mdiAccountTie"
|
||||
:icon="PhBracketsCurly"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.discordRoles?.includes(RoleConstants.MODERATOR)"
|
||||
label="Moderator"
|
||||
color="slight_danger"
|
||||
:icon="mdiAccountTieHat"
|
||||
:icon="PhShieldChevron"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.discordRoles?.includes(RoleConstants.BETA_TESTER)"
|
||||
label="Beta Tester"
|
||||
color="warning"
|
||||
:icon="mdiTestTube"
|
||||
:icon="PhTestTube"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.discordRoles?.includes(RoleConstants.DONOR)"
|
||||
label="Donor"
|
||||
color="gold"
|
||||
:icon="mdiHandCoinOutline"
|
||||
:icon="PhHandCoins"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.discordRoles?.includes(RoleConstants.BLAHAJ)"
|
||||
label="Blåhaj"
|
||||
color="info"
|
||||
:icon="mdiSharkFinOutline"
|
||||
:icon="PhFish"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.discordRoles?.includes(RoleConstants.RHYTHM_RIOT)"
|
||||
label="Rhythm Riot"
|
||||
color="sakura"
|
||||
:icon="mdiFlowerPoppy"
|
||||
:icon="PhFlower"
|
||||
small
|
||||
/>
|
||||
<PillTag
|
||||
v-if="cardData.userCustomize?.shrimpLinks"
|
||||
label="Shrimp Links"
|
||||
color="sakura"
|
||||
:icon="mdiLinkBoxVariantOutline"
|
||||
:icon="PhShrimp"
|
||||
small
|
||||
/>
|
||||
<!-- <PillTag
|
||||
label="Public Profile"
|
||||
color="success"
|
||||
:icon="mdiAccountCheck"
|
||||
/> -->
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
<script setup>
|
||||
import {
|
||||
mdiForwardburger,
|
||||
mdiBackburger,
|
||||
mdiMenu,
|
||||
mdiMonitor,
|
||||
mdiStoreCog,
|
||||
mdiStorePlus,
|
||||
mdiGamepad,
|
||||
mdiSecurity,
|
||||
mdiMultimedia,
|
||||
} from "@mdi/js";
|
||||
PhCaretDoubleLeft,
|
||||
PhDotsThreeCircle,
|
||||
PhMonitor,
|
||||
PhStorefront,
|
||||
PhStackPlus,
|
||||
PhJoystick,
|
||||
PhCrown,
|
||||
PhFilmSlate,
|
||||
} from "@phosphor-icons/vue";
|
||||
import { ref, watch, onMounted, computed } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import menuNavBar from "@/menuNavBar.js";
|
||||
|
|
@ -173,12 +172,12 @@ const menuAside = computed(() => {
|
|||
},
|
||||
];
|
||||
|
||||
var sideMenu = [{ to: "/", icon: mdiMonitor, label: "Dashboard" }];
|
||||
var sideMenu = [{ to: "/", icon: PhMonitor, label: "Dashboard" }];
|
||||
|
||||
if (mainStore.userAdmin) {
|
||||
sideMenu.push({
|
||||
label: "Admin",
|
||||
icon: mdiSecurity,
|
||||
icon: PhCrown,
|
||||
menu: adminMenu,
|
||||
});
|
||||
}
|
||||
|
|
@ -186,14 +185,14 @@ const menuAside = computed(() => {
|
|||
if (sortedGames.length) {
|
||||
sideMenu.push({
|
||||
label: "Games",
|
||||
icon: mdiGamepad,
|
||||
icon: PhJoystick,
|
||||
menu: sortedGames,
|
||||
});
|
||||
}
|
||||
|
||||
sideMenu.push({
|
||||
label: "My Content",
|
||||
icon: mdiMultimedia,
|
||||
icon: PhFilmSlate,
|
||||
menu: [
|
||||
{
|
||||
label: "Play Videos",
|
||||
|
|
@ -209,14 +208,14 @@ const menuAside = computed(() => {
|
|||
if (sortedArcades.length) {
|
||||
sideMenu.push({
|
||||
label: "My Arcades",
|
||||
icon: mdiStoreCog,
|
||||
icon: PhStorefront,
|
||||
menu: sortedArcades,
|
||||
});
|
||||
}
|
||||
|
||||
sideMenu.push({
|
||||
label: "Claim Arcade",
|
||||
icon: mdiStorePlus,
|
||||
icon: PhStackPlus,
|
||||
to: `/arcade/claim`,
|
||||
});
|
||||
|
||||
|
|
@ -265,15 +264,18 @@ const menuAside = computed(() => {
|
|||
@click.prevent="isAsideMobileExpanded = !isAsideMobileExpanded"
|
||||
>
|
||||
<BaseIcon
|
||||
:path="isAsideMobileExpanded ? mdiBackburger : mdiForwardburger"
|
||||
size="24"
|
||||
:icon="PhCaretDoubleLeft"
|
||||
:size="24"
|
||||
fill="bold"
|
||||
class="flex-none transition-transform duration-150 ease-in-out"
|
||||
:class="[isAsideMobileExpanded ? 'rotate-0' : 'rotate-180']"
|
||||
/>
|
||||
</NavBarItemPlain>
|
||||
<NavBarItemPlain
|
||||
display="hidden lg:flex xl:hidden"
|
||||
@click.prevent="isAsideLgActive = true"
|
||||
>
|
||||
<BaseIcon :path="mdiMenu" size="24" />
|
||||
<BaseIcon :icon="PhDotsThreeCircle" size="24" />
|
||||
</NavBarItemPlain>
|
||||
|
||||
<div class="h-full flex place-items-center ml-4 gap-4">
|
||||
|
|
|
|||
|
|
@ -1,45 +1,46 @@
|
|||
import {
|
||||
mdiAccount,
|
||||
mdiLogout,
|
||||
mdiBrushVariant,
|
||||
mdiServerNetwork,
|
||||
mdiCardAccountDetailsOutline,
|
||||
mdiAccountArrowLeftOutline,
|
||||
} from "@mdi/js";
|
||||
PhUser,
|
||||
PhSignOut,
|
||||
PhPaintBrushBroad,
|
||||
PhCloud,
|
||||
PhIdentificationCard,
|
||||
PhUserSwitch,
|
||||
} from "@phosphor-icons/vue";
|
||||
|
||||
export default [
|
||||
{
|
||||
isCurrentUser: true,
|
||||
menu: [
|
||||
{
|
||||
icon: mdiAccount,
|
||||
icon: PhUser,
|
||||
label: "Settings",
|
||||
to: "/profile",
|
||||
},
|
||||
{
|
||||
icon: mdiBrushVariant,
|
||||
icon: PhPaintBrushBroad,
|
||||
label: "Customize",
|
||||
to: "/profile/customize",
|
||||
},
|
||||
{
|
||||
icon: mdiServerNetwork,
|
||||
icon: PhCloud,
|
||||
label: "Integrations",
|
||||
to: "/profile/integrate",
|
||||
},
|
||||
{
|
||||
icon: mdiCardAccountDetailsOutline,
|
||||
icon: PhIdentificationCard,
|
||||
label: "Login Cards",
|
||||
to: "/profile/cards",
|
||||
},
|
||||
{
|
||||
icon: mdiAccountArrowLeftOutline,
|
||||
icon: PhUserSwitch,
|
||||
label: "Claim Profile",
|
||||
to: "/profile/claim",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: mdiLogout,
|
||||
icon: PhSignOut,
|
||||
fill: "regular",
|
||||
label: "Log out",
|
||||
isLogout: true,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -273,17 +273,6 @@ const routes = [
|
|||
hotReload: true, // disables Hot Reload
|
||||
},
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
title: "All Players",
|
||||
},
|
||||
path: "/games/:id/players/",
|
||||
name: "players_page",
|
||||
component: () => import("@/views/Game/PlayersView.vue"),
|
||||
options: {
|
||||
hotReload: true, // disables Hot Reload
|
||||
},
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
title: "View Profile",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { mdiCloudKeyOutline, mdiKeyPlus } from "@mdi/js";
|
||||
import { PhDatabase, PhKey } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import GeneralTable from "@/components/GeneralTable.vue";
|
||||
|
|
@ -89,7 +89,7 @@ const copyToClipboard = (item) => {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiCloudKeyOutline"
|
||||
:icon="PhDatabase"
|
||||
title="All Active Clients"
|
||||
color="text-blue-400"
|
||||
main
|
||||
|
|
@ -113,7 +113,7 @@ const copyToClipboard = (item) => {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiKeyPlus"
|
||||
:icon="PhKey"
|
||||
title="Create New Client"
|
||||
color="text-emerald-600"
|
||||
main
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import {
|
||||
mdiStoreOutline,
|
||||
mdiStoreEditOutline,
|
||||
mdiStorePlusOutline,
|
||||
} from "@mdi/js";
|
||||
PhStorefront,
|
||||
PhMagnifyingGlass,
|
||||
PhPlusCircle,
|
||||
} from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import GeneralTable from "@/components/GeneralTable.vue";
|
||||
|
|
@ -133,7 +133,7 @@ async function findMachine() {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiStoreEditOutline"
|
||||
:icon="PhMagnifyingGlass"
|
||||
title="Search Arcades"
|
||||
color="text-amber-600"
|
||||
main
|
||||
|
|
@ -207,7 +207,7 @@ async function findMachine() {
|
|||
</div>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiStoreOutline"
|
||||
:icon="PhStorefront"
|
||||
title="All Arcades"
|
||||
color="text-blue-400"
|
||||
main
|
||||
|
|
@ -230,7 +230,7 @@ async function findMachine() {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiStorePlusOutline"
|
||||
:icon="PhPlusCircle"
|
||||
title="Create Arcade"
|
||||
color="text-emerald-600"
|
||||
main
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { mdiFlagCheckered, mdiSecurity } from "@mdi/js";
|
||||
import { PhFlagCheckered, PhCrown } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import CardBoxWidget from "@/components/CardBoxWidget.vue";
|
||||
|
|
@ -126,7 +126,7 @@ function formatEvents(events) {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiSecurity"
|
||||
:icon="PhCrown"
|
||||
title="Admin Dashboard"
|
||||
color="text-red-600"
|
||||
main
|
||||
|
|
@ -173,8 +173,12 @@ function formatEvents(events) {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<SectionTitleLine :icon="mdiFlagCheckered" title="Recent PCB Events" />
|
||||
<CardBox has-table>
|
||||
<SectionTitleLine
|
||||
:icon="PhFlagCheckered"
|
||||
main
|
||||
title="Recent PCB Events"
|
||||
/>
|
||||
<CardBox has-table class="mb-6">
|
||||
<div
|
||||
class="bg-white dark:bg-slate-900/95 rounded-2xl lg:flex lg:justify-between"
|
||||
>
|
||||
|
|
@ -188,7 +192,8 @@ function formatEvents(events) {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiFlagCheckered"
|
||||
:icon="PhFlagCheckered"
|
||||
main
|
||||
title="Recent PASELI Transactions"
|
||||
/>
|
||||
<CardBox has-table>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { mdiFlagCheckered, mdiCashEdit, mdiExclamationThick } from "@mdi/js";
|
||||
import { PhFlagCheckered, PhCashRegister, PhSiren } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
|
|
@ -204,7 +204,7 @@ function extractExceptionData(xmlString) {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiExclamationThick"
|
||||
:icon="PhSiren"
|
||||
title="Recent Tracebacks"
|
||||
color="text-red-400"
|
||||
main
|
||||
|
|
@ -223,7 +223,7 @@ function extractExceptionData(xmlString) {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiFlagCheckered"
|
||||
:icon="PhFlagCheckered"
|
||||
title="Recent PCB Events"
|
||||
color="text-amber-400"
|
||||
main
|
||||
|
|
@ -242,7 +242,7 @@ function extractExceptionData(xmlString) {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiCashEdit"
|
||||
:icon="PhCashRegister"
|
||||
title="Recent PASELI Transactions"
|
||||
color="text-emerald-400"
|
||||
main
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { mdiWrenchCogOutline, mdiWrenchClock } from "@mdi/js";
|
||||
import { PhWrench, PhClockCountdown } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import GeneralTable from "@/components/GeneralTable.vue";
|
||||
|
|
@ -92,7 +92,7 @@ async function enterMaintenance() {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiWrenchCogOutline"
|
||||
:icon="PhWrench"
|
||||
title="Recent Maintenance Periods"
|
||||
color="text-blue-400"
|
||||
main
|
||||
|
|
@ -109,7 +109,7 @@ async function enterMaintenance() {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiWrenchClock"
|
||||
:icon="PhClockCountdown"
|
||||
title="Create Maintenance Period"
|
||||
color="text-yellow-600"
|
||||
main
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@
|
|||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import {
|
||||
mdiNewspaper,
|
||||
mdiNewspaperVariantMultipleOutline,
|
||||
mdiNewspaperMinus,
|
||||
mdiNewspaperPlus,
|
||||
} from "@mdi/js";
|
||||
PhNewspaperClipping,
|
||||
PhNewspaper,
|
||||
PhPlusCircle,
|
||||
PhMinusCircle,
|
||||
PhPencilCircle,
|
||||
} from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import GeneralTable from "@/components/GeneralTable.vue";
|
||||
|
|
@ -145,7 +146,7 @@ function getSelectedNews(newsId) {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiNewspaper"
|
||||
:icon="PhNewspaperClipping"
|
||||
title="Post Management"
|
||||
color="text-emerald-600"
|
||||
main
|
||||
|
|
@ -156,7 +157,7 @@ function getSelectedNews(newsId) {
|
|||
<PillTag
|
||||
color="success"
|
||||
label="Create Post"
|
||||
:icon="mdiNewspaperPlus"
|
||||
:icon="PhPlusCircle"
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
|
|
@ -176,6 +177,7 @@ function getSelectedNews(newsId) {
|
|||
color="success"
|
||||
label="Create"
|
||||
:small="false"
|
||||
:icon="PhPlusCircle"
|
||||
/>
|
||||
</div>
|
||||
</CardBox>
|
||||
|
|
@ -184,7 +186,7 @@ function getSelectedNews(newsId) {
|
|||
<PillTag
|
||||
color="warning"
|
||||
label="Edit Post"
|
||||
:icon="mdiNewspaperMinus"
|
||||
:icon="PhMinusCircle"
|
||||
class="mb-2"
|
||||
/>
|
||||
<FormField label="Post">
|
||||
|
|
@ -216,7 +218,7 @@ function getSelectedNews(newsId) {
|
|||
color="info"
|
||||
label="Update"
|
||||
:small="false"
|
||||
:icon="mdiNewspaper"
|
||||
:icon="PhPencilCircle"
|
||||
@click="updateNews()"
|
||||
/>
|
||||
|
||||
|
|
@ -224,7 +226,7 @@ function getSelectedNews(newsId) {
|
|||
color="danger"
|
||||
label="Delete Post"
|
||||
:small="false"
|
||||
:icon="mdiNewspaperMinus"
|
||||
:icon="PhMinusCircle"
|
||||
@click="deleteNews()"
|
||||
/>
|
||||
</BaseButtons>
|
||||
|
|
@ -233,7 +235,7 @@ function getSelectedNews(newsId) {
|
|||
</div>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiNewspaperVariantMultipleOutline"
|
||||
:icon="PhNewspaper"
|
||||
title="All News"
|
||||
color="text-blue-400"
|
||||
main
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { reactive } from "vue";
|
||||
import { mdiUpdate, mdiCloudUploadOutline } from "@mdi/js";
|
||||
import { PhCloudArrowDown, PhCloudArrowUp } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import CardBoxWidget from "@/components/CardBoxWidget.vue";
|
||||
|
|
@ -30,9 +30,9 @@ const newUpdate = reactive({
|
|||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<SectionTitleLine
|
||||
:icon="mdiUpdate"
|
||||
:icon="PhCloudArrowDown"
|
||||
title="OTA Update Administration"
|
||||
color="text-red-600"
|
||||
color="text-sky-500"
|
||||
main
|
||||
/>
|
||||
|
||||
|
|
@ -41,8 +41,9 @@ const newUpdate = reactive({
|
|||
</div>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiCloudUploadOutline"
|
||||
:icon="PhCloudArrowUp"
|
||||
title="Add an Update"
|
||||
color="text-emerald-500"
|
||||
main
|
||||
/>
|
||||
<CardBox is-form class="row-span-1">
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
import { reactive, ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import {
|
||||
mdiInformationOutline,
|
||||
mdiCogOutline,
|
||||
mdiSailBoat,
|
||||
mdiCheckOutline,
|
||||
mdiCloseOutline,
|
||||
} from "@mdi/js";
|
||||
PhInfo,
|
||||
PhGear,
|
||||
PhSailboat,
|
||||
PhCheckCircle,
|
||||
PhXCircle,
|
||||
} from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
|
|
@ -262,7 +262,7 @@ async function onboardArcade(exportArcade) {
|
|||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<SectionTitleLine
|
||||
:icon="mdiSailBoat"
|
||||
:icon="PhSailboat"
|
||||
title="Arcade Onboarding"
|
||||
color="text-green-400"
|
||||
main
|
||||
|
|
@ -273,7 +273,7 @@ async function onboardArcade(exportArcade) {
|
|||
<PillTag
|
||||
color="info"
|
||||
label="General Information"
|
||||
:icon="mdiInformationOutline"
|
||||
:icon="PhInfo"
|
||||
class="mb-2"
|
||||
/>
|
||||
<FormField label="Arcade Name">
|
||||
|
|
@ -289,13 +289,13 @@ async function onboardArcade(exportArcade) {
|
|||
<BaseButton color="info" label="Check Name" @click="checkName()" />
|
||||
<BaseIcon
|
||||
v-if="arcadeCheck == true"
|
||||
:path="mdiCheckOutline"
|
||||
:icon="PhCheckCircle"
|
||||
color="text-green-400"
|
||||
size="25"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else-if="arcadeCheck == false"
|
||||
:path="mdiCloseOutline"
|
||||
:icon="PhXCircle"
|
||||
color="text-red-400"
|
||||
size="25"
|
||||
/>
|
||||
|
|
@ -338,12 +338,7 @@ async function onboardArcade(exportArcade) {
|
|||
</CardBox>
|
||||
|
||||
<CardBox is-form class="row-span-1">
|
||||
<PillTag
|
||||
color="info"
|
||||
label="Settings"
|
||||
:icon="mdiCogOutline"
|
||||
class="mb-2"
|
||||
/>
|
||||
<PillTag color="info" label="Settings" :icon="PhGear" class="mb-2" />
|
||||
<div
|
||||
class="grid grid-cols-1 w-full gap-2 md:gap-6 md:flex md:place-content-stretch"
|
||||
>
|
||||
|
|
@ -406,13 +401,7 @@ async function onboardArcade(exportArcade) {
|
|||
</CardBox>
|
||||
|
||||
<CardBox class="row-span-1">
|
||||
<PillTag
|
||||
color="info"
|
||||
label="Machines"
|
||||
:icon="mdiInformationOutline"
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
<PillTag color="info" label="Machines" :icon="PhInfo" class="mb-2" />
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<form class="h-full" @submit.prevent="addMachine()">
|
||||
<FormField
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { mdiAccountBadgeOutline } from "@mdi/js";
|
||||
import { PhUsersThree, PhMagnifyingGlass } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import GeneralTable from "@/components/GeneralTable.vue";
|
||||
|
|
@ -129,6 +129,12 @@ async function findUser() {
|
|||
<p class="text-sm text-gray-400">Click a row to open User</p>
|
||||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="PhMagnifyingGlass"
|
||||
title="Search"
|
||||
color="text-amber-500"
|
||||
main
|
||||
/>
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<CardBox class="mb-6">
|
||||
<PillTag color="info" label="Search" class="mb-2" />
|
||||
|
|
@ -201,7 +207,7 @@ async function findUser() {
|
|||
</div>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccountBadgeOutline"
|
||||
:icon="PhUsersThree"
|
||||
title="All Users"
|
||||
color="text-blue-400"
|
||||
main
|
||||
|
|
|
|||
|
|
@ -2,14 +2,12 @@
|
|||
import { useRoute, useRouter } from "vue-router";
|
||||
import { ref, onMounted, watch } from "vue";
|
||||
import {
|
||||
mdiStore,
|
||||
mdiStoreCog,
|
||||
mdiCogOutline,
|
||||
mdiShieldEditOutline,
|
||||
mdiCheckOutline,
|
||||
mdiCloseOutline,
|
||||
mdiInformationOutline,
|
||||
} from "@mdi/js";
|
||||
PhStorefront,
|
||||
PhGear,
|
||||
PhCheckCircle,
|
||||
PhXCircle,
|
||||
PhInfo,
|
||||
} from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
|
|
@ -248,11 +246,7 @@ async function adminDeleteArcade() {
|
|||
<ArcadeCard class="mb-6" :arcade="arcadeData" />
|
||||
|
||||
<template v-if="mainStore.userAdmin">
|
||||
<SectionTitleLine
|
||||
:icon="mdiShieldEditOutline"
|
||||
title="Arcade Administration"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhGear" title="Arcade Administration" main />
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
<CardBox
|
||||
is-form
|
||||
|
|
@ -262,7 +256,7 @@ async function adminDeleteArcade() {
|
|||
<PillTag
|
||||
color="info"
|
||||
label="General Information"
|
||||
:icon="mdiInformationOutline"
|
||||
:icon="PhInfo"
|
||||
class="mb-2"
|
||||
/>
|
||||
<FormField label="Arcade Name">
|
||||
|
|
@ -282,13 +276,13 @@ async function adminDeleteArcade() {
|
|||
/>
|
||||
<BaseIcon
|
||||
v-if="arcadeCheck == true"
|
||||
:path="mdiCheckOutline"
|
||||
:icon="PhCheckCircle"
|
||||
color="text-green-400"
|
||||
size="25"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else-if="arcadeCheck == false"
|
||||
:path="mdiCloseOutline"
|
||||
:icon="PhXCircle"
|
||||
color="text-red-400"
|
||||
size="25"
|
||||
/>
|
||||
|
|
@ -336,7 +330,7 @@ async function adminDeleteArcade() {
|
|||
<PillTag
|
||||
color="info"
|
||||
label="Add Manager"
|
||||
:icon="mdiInformationOutline"
|
||||
:icon="PhInfo"
|
||||
class="mb-2"
|
||||
/>
|
||||
<form class="h-full" @submit.prevent="addManager">
|
||||
|
|
@ -392,14 +386,9 @@ async function adminDeleteArcade() {
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<SectionTitleLine :icon="mdiStoreCog" title="Arcade Management" main />
|
||||
<SectionTitleLine :icon="PhGear" title="Arcade Management" main />
|
||||
<CardBox is-form class="mb-6" @submit.prevent="updateArcade">
|
||||
<PillTag
|
||||
color="info"
|
||||
label="Settings"
|
||||
:icon="mdiCogOutline"
|
||||
class="mb-2"
|
||||
/>
|
||||
<PillTag color="info" label="Settings" :icon="PhGear" class="mb-2" />
|
||||
<div
|
||||
class="grid grid-cols-1 w-full gap-2 md:gap-6 md:flex md:place-content-stretch"
|
||||
>
|
||||
|
|
@ -447,7 +436,7 @@ async function adminDeleteArcade() {
|
|||
/>
|
||||
</CardBox>
|
||||
|
||||
<SectionTitleLine :icon="mdiStore" title="Arcade Overview" main />
|
||||
<SectionTitleLine :icon="PhStorefront" title="Arcade Overview" main />
|
||||
|
||||
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 mb-6">
|
||||
<CardBoxWidget
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import {
|
||||
mdiStorePlus,
|
||||
mdiScriptTextKeyOutline,
|
||||
mdiLoading,
|
||||
mdiAccountConvertOutline,
|
||||
} from "@mdi/js";
|
||||
PhSpinnerBall,
|
||||
PhUnite,
|
||||
PhTextbox,
|
||||
PhStorefront,
|
||||
PhQuestion,
|
||||
} from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
|
|
@ -56,7 +57,7 @@ async function saveSettings() {
|
|||
<UserCard class="mb-6" use-small even-smaller />
|
||||
|
||||
<template v-if="!takeoverData">
|
||||
<SectionTitleLine :icon="mdiStorePlus" title="Claim an Arcade" main />
|
||||
<SectionTitleLine :icon="PhStorefront" title="Claim an Arcade" main />
|
||||
<CardBox
|
||||
is-form
|
||||
class="row-span-2 mb-6"
|
||||
|
|
@ -73,7 +74,7 @@ async function saveSettings() {
|
|||
>
|
||||
<FormControl
|
||||
v-model="arcadeForm.PCBID"
|
||||
:icon="mdiScriptTextKeyOutline"
|
||||
:icon="PhTextbox"
|
||||
name="cardId"
|
||||
type="pcbid"
|
||||
placeholder="XXXXXXXXXXXXXXXXX"
|
||||
|
|
@ -87,7 +88,7 @@ async function saveSettings() {
|
|||
<BaseButton type="submit" color="success" label="Start Claim" />
|
||||
<BaseIcon
|
||||
v-if="cardLoading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
@ -96,7 +97,7 @@ async function saveSettings() {
|
|||
</template>
|
||||
|
||||
<div v-if="takeoverData && saveState == null">
|
||||
<SectionTitleLine :icon="mdiStorePlus" title="Confirm Merge" main />
|
||||
<SectionTitleLine :icon="PhQuestion" title="Confirm Merge" main />
|
||||
<CardBox>
|
||||
<h2 class="text-2xl font-bold">
|
||||
{{ takeoverData?.arcade?.name }}
|
||||
|
|
@ -120,11 +121,7 @@ async function saveSettings() {
|
|||
</div>
|
||||
|
||||
<div v-if="saveState == true">
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccountConvertOutline"
|
||||
title="Takeover Results"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhUnite" title="Takeover Results" main />
|
||||
|
||||
<CardBox>
|
||||
<h2 class="text-xl mb-6">
|
||||
|
|
@ -142,14 +139,10 @@ async function saveSettings() {
|
|||
</div>
|
||||
|
||||
<div v-if="saveState == false">
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccountConvertOutline"
|
||||
title="Merge Results"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhUnite" title="Takeover Results" main />
|
||||
|
||||
<CardBox>
|
||||
<h2 class="text-xl mb-6">❌ Failed to merge. Please try again.</h2>
|
||||
<h2 class="text-xl mb-6">❌ Failed to takeover. Please try again.</h2>
|
||||
|
||||
<div class="mt-4">
|
||||
<BaseButton color="warning" label="Retry" @click="saveSettings" />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { reactive, ref, watch, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { mdiNewspaperVariantMultiple } from "@mdi/js";
|
||||
import { PhNewspaper } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
|
|
@ -164,7 +164,7 @@ watch(
|
|||
<template v-if="!loading">
|
||||
<ArcadeCard class="mb-6" :arcade="arcadeData" :use-small="true" />
|
||||
<SectionTitleLine
|
||||
:icon="mdiNewspaperVariantMultiple"
|
||||
:icon="PhNewspaper"
|
||||
title="Game Event Settings"
|
||||
main
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import {
|
||||
mdiDatabasePlusOutline,
|
||||
mdiDatabaseEditOutline,
|
||||
mdiGamepad,
|
||||
mdiShieldEditOutline,
|
||||
} from "@mdi/js";
|
||||
PhPlusCircle,
|
||||
PhPencilCircle,
|
||||
PhJoystick,
|
||||
PhGear,
|
||||
} from "@phosphor-icons/vue";
|
||||
import { useMainStore } from "@/stores/main";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -193,7 +193,7 @@ async function deleteMachine() {
|
|||
|
||||
<template v-if="mainStore.userAdmin">
|
||||
<SectionTitleLine
|
||||
:icon="mdiShieldEditOutline"
|
||||
:icon="PhGear"
|
||||
title="Machine Administration"
|
||||
main
|
||||
/>
|
||||
|
|
@ -202,7 +202,7 @@ async function deleteMachine() {
|
|||
<PillTag
|
||||
color="success"
|
||||
label="Add Machine"
|
||||
:icon="mdiDatabasePlusOutline"
|
||||
:icon="PhPlusCircle"
|
||||
class="mb-2"
|
||||
/>
|
||||
<form class="h-full" @submit.prevent="addMachine()">
|
||||
|
|
@ -265,7 +265,7 @@ async function deleteMachine() {
|
|||
<PillTag
|
||||
color="warning"
|
||||
label="Edit Machine"
|
||||
:icon="mdiDatabaseEditOutline"
|
||||
:icon="PhPencilCircle"
|
||||
class="mb-2"
|
||||
/>
|
||||
<FormField label="Machine">
|
||||
|
|
@ -330,7 +330,7 @@ async function deleteMachine() {
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<SectionTitleLine :icon="mdiGamepad" title="Machines" main />
|
||||
<SectionTitleLine :icon="PhJoystick" title="Machines" main />
|
||||
<CardBox has-table>
|
||||
<div
|
||||
class="bg-white dark:bg-slate-900/95 rounded-2xl lg:flex lg:justify-between"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { mdiCashRegister, mdiAccountCash } from "@mdi/js";
|
||||
import { PhCashRegister, PhCurrencyJpy } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import GeneralTable from "@/components/GeneralTable.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -99,7 +99,7 @@ function filterTransactions(transactions) {
|
|||
<template v-if="!loading && arcadeData">
|
||||
<ArcadeCard class="mb-6" :arcade="arcadeData" :use-small="true" />
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccountCash"
|
||||
:icon="PhCurrencyJpy"
|
||||
title="Player PASELI Balances"
|
||||
main
|
||||
/>
|
||||
|
|
@ -117,7 +117,7 @@ function filterTransactions(transactions) {
|
|||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiCashRegister"
|
||||
:icon="PhCashRegister"
|
||||
title="PASELI Transaction History"
|
||||
main
|
||||
class="pt-6"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { reactive } from "vue";
|
||||
import { mdiStorefront } from "@mdi/js";
|
||||
import { PhStorefront } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
|
|
@ -34,7 +34,7 @@ export default {
|
|||
<template>
|
||||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<SectionTitleLine :icon="mdiStorefront" title="Public Arcades" main />
|
||||
<SectionTitleLine :icon="PhStorefront" title="Public Arcades" main />
|
||||
|
||||
<FormField label="Search" class="md:w-1/2 lg:w-1/3">
|
||||
<FormControl v-model="filterForm.filter" name="search" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
import { mdiAccount, mdiAsterisk } from "@mdi/js";
|
||||
import { PhUser, PhPassword } from "@phosphor-icons/vue";
|
||||
import { reactive } from "vue";
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -67,7 +67,7 @@ const submit = async () => {
|
|||
<FormField label="Username">
|
||||
<FormControl
|
||||
v-model="form.login"
|
||||
:icon="mdiAccount"
|
||||
:icon="PhUser"
|
||||
name="login"
|
||||
autocomplete="username"
|
||||
required
|
||||
|
|
@ -77,7 +77,7 @@ const submit = async () => {
|
|||
<FormField label="Password">
|
||||
<FormControl
|
||||
v-model="form.pass"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
type="password"
|
||||
name="password"
|
||||
autocomplete="current-password"
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
import { reactive, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import {
|
||||
mdiAccount,
|
||||
mdiMail,
|
||||
mdiAsterisk,
|
||||
mdiCardAccountDetailsOutline,
|
||||
mdiLoading,
|
||||
} from "@mdi/js";
|
||||
PhUser,
|
||||
PhAt,
|
||||
PhPassword,
|
||||
PhCreditCard,
|
||||
PhSpinnerBall,
|
||||
} from "@phosphor-icons/vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormCheckRadio from "@/components/FormCheckRadio.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
|
|
@ -92,7 +92,7 @@ async function registerProfile() {
|
|||
<FormField label="Desired Username">
|
||||
<FormControl
|
||||
v-model="profileForm.username"
|
||||
:icon="mdiAccount"
|
||||
:icon="PhUser"
|
||||
name="username"
|
||||
required
|
||||
autocomplete="username"
|
||||
|
|
@ -102,7 +102,7 @@ async function registerProfile() {
|
|||
<FormField label="Email Address">
|
||||
<FormControl
|
||||
v-model="profileForm.email"
|
||||
:icon="mdiMail"
|
||||
:icon="PhAt"
|
||||
type="email"
|
||||
name="email"
|
||||
required
|
||||
|
|
@ -113,7 +113,7 @@ async function registerProfile() {
|
|||
<FormField label="Password">
|
||||
<FormControl
|
||||
v-model="profileForm.newPassword"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
name="newPassword"
|
||||
type="password"
|
||||
required
|
||||
|
|
@ -123,7 +123,7 @@ async function registerProfile() {
|
|||
<FormField label="Password Confirmation">
|
||||
<FormControl
|
||||
v-model="profileForm.confirmPassword"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
name="confirmPassword"
|
||||
type="password"
|
||||
required
|
||||
|
|
@ -136,7 +136,7 @@ async function registerProfile() {
|
|||
>
|
||||
<FormControl
|
||||
v-model="profileForm.cardId"
|
||||
:icon="mdiCardAccountDetailsOutline"
|
||||
:icon="PhCreditCard"
|
||||
name="cardId"
|
||||
type="card"
|
||||
placeholder="XXXX-XXXX-XXXX-XXXX"
|
||||
|
|
@ -150,7 +150,7 @@ async function registerProfile() {
|
|||
<FormField label="Game PIN">
|
||||
<FormControl
|
||||
v-model="profileForm.pin"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
type="password"
|
||||
name="pin"
|
||||
required
|
||||
|
|
@ -175,7 +175,7 @@ async function registerProfile() {
|
|||
<BaseButton type="submit" label="Register" color="success" />
|
||||
<BaseIcon
|
||||
v-if="registerLoading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
<script setup>
|
||||
import { reactive } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import {
|
||||
mdiEmailOutline,
|
||||
mdiShieldKeyOutline,
|
||||
mdiAsterisk,
|
||||
mdiLoading,
|
||||
} from "@mdi/js";
|
||||
import { PhAt, PhKey, PhPassword, PhSpinnerBall } from "@phosphor-icons/vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
|
|
@ -98,7 +93,7 @@ async function resetPassword() {
|
|||
<FormField label="Email Address">
|
||||
<FormControl
|
||||
v-model="form.email"
|
||||
:icon="mdiEmailOutline"
|
||||
:icon="PhAt"
|
||||
type="email"
|
||||
autocomplete="email"
|
||||
required
|
||||
|
|
@ -107,7 +102,7 @@ async function resetPassword() {
|
|||
<BaseButton label="Check" type="submit" color="info" />
|
||||
<BaseIcon
|
||||
v-if="form.loading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
@ -119,7 +114,7 @@ async function resetPassword() {
|
|||
<FormField label="Auth Key">
|
||||
<FormControl
|
||||
v-model="form.authKey"
|
||||
:icon="mdiShieldKeyOutline"
|
||||
:icon="PhKey"
|
||||
type="text"
|
||||
name="token"
|
||||
inputmode="numeric"
|
||||
|
|
@ -131,7 +126,7 @@ async function resetPassword() {
|
|||
<BaseButton label="Unlock" type="submit" color="info" />
|
||||
<BaseIcon
|
||||
v-if="form.loading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
@ -151,7 +146,7 @@ async function resetPassword() {
|
|||
<FormField label="New Password">
|
||||
<FormControl
|
||||
v-model="form.newPassword"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
type="password"
|
||||
required
|
||||
minlength="8"
|
||||
|
|
@ -160,7 +155,7 @@ async function resetPassword() {
|
|||
<FormField label="Confirm Password">
|
||||
<FormControl
|
||||
v-model="form.confirmPassword"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
type="password"
|
||||
required
|
||||
minlength="8"
|
||||
|
|
@ -173,7 +168,7 @@ async function resetPassword() {
|
|||
/>
|
||||
<BaseIcon
|
||||
v-if="form.loading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { reactive, onMounted, watch, ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { mdiAccountTieHat } from "@mdi/js";
|
||||
import { PhUserGear } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
|
|
@ -141,7 +141,6 @@ async function updateProfile() {
|
|||
:game="gameID"
|
||||
:version="versionForm.currentVersion"
|
||||
:profile="myProfile"
|
||||
use-small
|
||||
>
|
||||
</ProfileCard>
|
||||
</div>
|
||||
|
|
@ -149,7 +148,7 @@ async function updateProfile() {
|
|||
|
||||
<SectionTitleLine
|
||||
v-if="versionForm.currentVersion"
|
||||
:icon="mdiAccountTieHat"
|
||||
:icon="PhUserGear"
|
||||
title="Profile Customizations"
|
||||
main
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { reactive, ref, onMounted, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { mdiAccountMultiple } from "@mdi/js";
|
||||
import { PhUsersThree } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import GameHeader from "@/components/Cards/GameHeader.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
|
|
@ -173,13 +173,12 @@ const navigateToProfile = (item) => {
|
|||
:game="gameID"
|
||||
:version="versionForm.currentVersion"
|
||||
:profile="myProfile"
|
||||
use-small
|
||||
>
|
||||
</ProfileCard>
|
||||
</div>
|
||||
</GameHeader>
|
||||
|
||||
<SectionTitleLine :icon="mdiAccountMultiple" title="All Players" main />
|
||||
<SectionTitleLine :icon="PhUsersThree" title="All Players" main />
|
||||
<CardBox has-table>
|
||||
<div
|
||||
class="bg-white dark:bg-slate-900/95 rounded-2xl lg:flex lg:justify-between"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted, reactive, computed } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { mdiFormatListNumbered } from "@mdi/js";
|
||||
import { PhRanking } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
|
|
@ -64,7 +64,7 @@ const filteredSongs = computed(() => {
|
|||
<LayoutAuthenticated>
|
||||
<SectionMain v-if="songData">
|
||||
<GameHeader :game="thisGame" />
|
||||
<SectionTitleLine :icon="mdiFormatListNumbered" title="Top Records" main>
|
||||
<SectionTitleLine :icon="PhRanking" title="Top Records" main>
|
||||
<template v-if="thisGame.versions">
|
||||
<div class="md:w-1/3 md:text-right">
|
||||
<h2 class="text-md sm:text-lg md:text-xl font-bold p-2">
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { ref, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useMainStore } from "@/stores/main";
|
||||
import { mdiCounter } from "@mdi/js";
|
||||
import { PhMedal } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
|
|
@ -166,7 +166,7 @@ const navigateToSong = (item) => {
|
|||
<GameHeader :game="thisGame" />
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiCounter"
|
||||
:icon="PhMedal"
|
||||
:title="`All ${
|
||||
thisGame.shortName ? thisGame.shortName : thisGame.name
|
||||
} Scores`"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted, reactive, computed } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { mdiFormatListNumbered } from "@mdi/js";
|
||||
import { PhRanking, PhUser, PhMedal } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
|
|
@ -89,16 +89,16 @@ const filteredSongs = computed(() => {
|
|||
<SectionMain v-if="songData">
|
||||
<template v-if="myProfile">
|
||||
<GameHeader :game="thisGame" :profile="myProfile" />
|
||||
<div class="flex gap-2 mb-2 md:mb-0">
|
||||
<div class="flex gap-2 mb-6 md:mb-0">
|
||||
<BaseButton
|
||||
:icon="mdiAccountDetails"
|
||||
:icon="PhUser"
|
||||
:href="`/#/games/${thisGame.id}/profiles/${myProfile.userId}`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
:label="`${myProfile.username}'s Profile`"
|
||||
/>
|
||||
<BaseButton
|
||||
:icon="mdiAccountDetails"
|
||||
:icon="PhMedal"
|
||||
:href="`/#/games/${thisGame.id}/scores/${myProfile.userId}`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
|
|
@ -106,7 +106,7 @@ const filteredSongs = computed(() => {
|
|||
/>
|
||||
</div>
|
||||
<SectionTitleLine
|
||||
:icon="mdiFormatListNumbered"
|
||||
:icon="PhRanking"
|
||||
:title="`${myProfile.username}'s ${
|
||||
thisGame.shortName ? thisGame.shortName : thisGame.name
|
||||
} Records`"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { ref, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useMainStore } from "@/stores/main";
|
||||
import { mdiCounter, mdiAccountDetails } from "@mdi/js";
|
||||
import { PhRanking, PhUser, PhMedal } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
|
|
@ -182,21 +182,29 @@ const navigateToSong = (item) => {
|
|||
<SectionMain>
|
||||
<template v-if="myProfile">
|
||||
<GameHeader :game="thisGame" :profile="myProfile" />
|
||||
<SectionTitleLine
|
||||
:icon="mdiCounter"
|
||||
:title="`${myProfile.username}'s ${
|
||||
thisGame.shortName ? thisGame.shortName : thisGame.name
|
||||
} Scores`"
|
||||
main
|
||||
>
|
||||
<div class="flex gap-2 mb-6">
|
||||
<BaseButton
|
||||
:icon="mdiAccountDetails"
|
||||
:icon="PhUser"
|
||||
:href="`/#/games/${thisGame.id}/profiles/${myProfile.userId}`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
:label="`${myProfile.username}'s Profile`"
|
||||
/>
|
||||
</SectionTitleLine>
|
||||
<BaseButton
|
||||
:icon="PhRanking"
|
||||
:href="`/#/games/${thisGame.id}/records/${myProfile.userId}`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
:label="`${myProfile.username}'s Records`"
|
||||
/>
|
||||
</div>
|
||||
<SectionTitleLine
|
||||
:icon="PhMedal"
|
||||
:title="`${myProfile.username}'s ${
|
||||
thisGame.shortName ? thisGame.shortName : thisGame.name
|
||||
} Scores`"
|
||||
main
|
||||
/>
|
||||
|
||||
<CardBox has-table>
|
||||
<GeneralTable
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@
|
|||
import { reactive, ref, onMounted, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import {
|
||||
mdiAccountOutline,
|
||||
mdiPlaylistMusicOutline,
|
||||
mdiFormatListText,
|
||||
mdiChartBarStacked,
|
||||
mdiChartAreasplineVariant,
|
||||
mdiChartTimeline,
|
||||
mdiStickerOutline,
|
||||
mdiChartDonutVariant,
|
||||
} from "@mdi/js";
|
||||
PhUser,
|
||||
PhCalendarDots,
|
||||
PhChartLine,
|
||||
PhRanking,
|
||||
PhMedal,
|
||||
PhChartPieSlice,
|
||||
PhSticker,
|
||||
PhTarget,
|
||||
} from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBoxWidget from "@/components/CardBoxWidget.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -359,7 +359,7 @@ async function generateTimeline(myProfile) {
|
|||
<template v-if="myProfile">
|
||||
<SectionMain>
|
||||
<GameHeader :game="thisGame" />
|
||||
<SectionTitleLine :icon="mdiAccountOutline" title="View Profile" main>
|
||||
<SectionTitleLine :icon="PhUser" title="View Profile" main>
|
||||
<div
|
||||
v-if="thisGame.versions && myProfile"
|
||||
class="mt-2 md:mt-0 md:w-1/3 md:text-right"
|
||||
|
|
@ -391,18 +391,17 @@ async function generateTimeline(myProfile) {
|
|||
>
|
||||
<div class="w-full">
|
||||
<ProfileCard
|
||||
use-small
|
||||
:game="gameID"
|
||||
:version="versionForm.currentVersion"
|
||||
:profile="myProfile"
|
||||
>
|
||||
<div
|
||||
v-if="!thisGame.noScores"
|
||||
class="md:w-1/3 grid grid-cols-1 md:grid-cols-2 gap-3"
|
||||
class="md:w-1/3 grid grid-cols-1 md:grid-cols-2 gap-3 mt-4"
|
||||
>
|
||||
<BaseButton
|
||||
:href="`/#/games/${gameID}/scores/${myProfile.userId}`"
|
||||
:icon="mdiPlaylistMusicOutline"
|
||||
:icon="PhMedal"
|
||||
class="w-full md:w-auto"
|
||||
color="info"
|
||||
label="View Scores"
|
||||
|
|
@ -410,7 +409,7 @@ async function generateTimeline(myProfile) {
|
|||
|
||||
<BaseButton
|
||||
:href="`/#/games/${gameID}/records/${myProfile.userId}`"
|
||||
:icon="mdiFormatListText"
|
||||
:icon="PhRanking"
|
||||
class="w-full md:w-auto"
|
||||
color="info"
|
||||
label="View Records"
|
||||
|
|
@ -525,11 +524,7 @@ async function generateTimeline(myProfile) {
|
|||
myProfile.battle_data
|
||||
"
|
||||
>
|
||||
<SectionTitleLine
|
||||
:icon="mdiChartAreasplineVariant"
|
||||
title="Stats"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhChartLine" title="Stats" main />
|
||||
<div
|
||||
class="my-6 grid grid-cols-2 md:grid-cols-5 xl:grid-cols-6 gap-6"
|
||||
>
|
||||
|
|
@ -671,11 +666,10 @@ async function generateTimeline(myProfile) {
|
|||
|
||||
<template v-if="myProfile.jubility">
|
||||
<SectionTitleLine
|
||||
:icon="mdiChartBarStacked"
|
||||
:icon="PhChartPieSlice"
|
||||
title="Jubility Breakdown"
|
||||
main
|
||||
/>
|
||||
|
||||
<div class="my-6 grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<CardBox v-if="myProfile.pick_up_breakdown">
|
||||
<PillTag label="Pick-Up" color="info" />
|
||||
|
|
@ -697,12 +691,7 @@ async function generateTimeline(myProfile) {
|
|||
</template>
|
||||
|
||||
<template v-if="myProfile?.trbitem">
|
||||
<SectionTitleLine
|
||||
:icon="mdiStickerOutline"
|
||||
title="Sticker Board"
|
||||
main
|
||||
/>
|
||||
|
||||
<SectionTitleLine :icon="PhSticker" title="Sticker Board" main />
|
||||
<div class="my-6">
|
||||
<CardBox class="w-full grid place-content-center">
|
||||
<UserSticker
|
||||
|
|
@ -720,11 +709,7 @@ async function generateTimeline(myProfile) {
|
|||
versionForm.currentVersion >= 29
|
||||
"
|
||||
>
|
||||
<SectionTitleLine
|
||||
:icon="mdiChartDonutVariant"
|
||||
title="Notes Radar"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhTarget" title="Notes Radar" main />
|
||||
<UserNotesRadar
|
||||
:game="thisGame.id"
|
||||
:version="versionForm.currentVersion"
|
||||
|
|
@ -733,8 +718,7 @@ async function generateTimeline(myProfile) {
|
|||
</template>
|
||||
|
||||
<template v-if="myProfile?.timeline">
|
||||
<SectionTitleLine :icon="mdiChartTimeline" title="Timeline" main />
|
||||
|
||||
<SectionTitleLine :icon="PhCalendarDots" title="Timeline" main />
|
||||
<div class="my-6">
|
||||
<CardBox>
|
||||
<ol
|
||||
|
|
|
|||
|
|
@ -1,170 +0,0 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import {
|
||||
mdiAccountMultiple,
|
||||
mdiPlaylistMusicOutline,
|
||||
mdiFormatListText,
|
||||
} from "@mdi/js";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
import GameTitleLine from "@/components/GameTitleLine.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import GeneralTable from "@/components/GeneralTable.vue";
|
||||
|
||||
import { APIGetAllProfiles } from "@/stores/api/profile";
|
||||
import { getGameInfo } from "@/constants";
|
||||
import { getCardStyle } from "@/constants/sources";
|
||||
import { dashCode } from "@/constants/userData";
|
||||
import { getIIDXDan } from "@/constants/danClass";
|
||||
|
||||
const $route = useRoute();
|
||||
const $router = useRouter();
|
||||
var gameID = null;
|
||||
var thisGame = null;
|
||||
|
||||
gameID = $route.params.id;
|
||||
thisGame = getGameInfo(gameID);
|
||||
|
||||
if (thisGame == null) {
|
||||
$router.push({
|
||||
name: "ErrorPage",
|
||||
params: {
|
||||
catchAll: "404",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const profiles = ref([]);
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const data = await APIGetAllProfiles(gameID);
|
||||
profiles.value = formatProfiles(data);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch profile data:", error);
|
||||
}
|
||||
});
|
||||
|
||||
const headers = [];
|
||||
headers.push({
|
||||
text: "Player",
|
||||
value: "username",
|
||||
sortable: true,
|
||||
width: 120,
|
||||
});
|
||||
|
||||
if (!thisGame.noRivals) {
|
||||
headers.push({ text: "Rival ID", value: "extid", width: 100 });
|
||||
}
|
||||
|
||||
headers.push(
|
||||
{ text: "Last Play", value: "stats.last_play_timestamp", width: 150 },
|
||||
{ text: "Last Arcade", value: "stats.last_play_arcade", width: 150 },
|
||||
{ text: "Plays", value: "stats.total_plays", sortable: true, width: 50 },
|
||||
);
|
||||
|
||||
if (thisGame.playerHeaders) {
|
||||
for (var header of thisGame.playerHeaders) {
|
||||
headers.push(header);
|
||||
}
|
||||
}
|
||||
|
||||
function formatProfiles(profiles) {
|
||||
var formattedItems = [];
|
||||
for (var item of profiles) {
|
||||
if (item.extid) {
|
||||
item.extid = dashCode(item.extid);
|
||||
}
|
||||
|
||||
if (item.stats) {
|
||||
if (item.stats.last_play_timestamp) {
|
||||
const date = new Date(item.stats.last_play_timestamp * 1000);
|
||||
item.stats.last_play_timestamp = date.toLocaleString();
|
||||
}
|
||||
|
||||
if (item.sgrade) {
|
||||
item.sgrade = getIIDXDan(item.sgrade).short;
|
||||
}
|
||||
|
||||
if (item.dgrade) {
|
||||
item.dgrade = getIIDXDan(item.dgrade).short;
|
||||
}
|
||||
}
|
||||
|
||||
formattedItems.push(item);
|
||||
}
|
||||
|
||||
formattedItems.sort((a, b) => {
|
||||
const totalPlaysA = a.stats ? a.stats.total_plays || 0 : 0;
|
||||
const totalPlaysB = b.stats ? b.stats.total_plays || 0 : 0;
|
||||
return totalPlaysB - totalPlaysA; // Sort in descending order
|
||||
});
|
||||
return formattedItems;
|
||||
}
|
||||
|
||||
const navigateToProfile = (item) => {
|
||||
const userID = item.userId;
|
||||
$router.push(`/games/${gameID}/profiles/${userID}`);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<div
|
||||
:style="getCardStyle(thisGame)"
|
||||
class="rounded-2xl mb-6 card-container"
|
||||
>
|
||||
<div
|
||||
class="bg-white dark:bg-slate-900/90 rounded-2xl pt-6 p-3 card-content"
|
||||
>
|
||||
<div class="w-full">
|
||||
<div
|
||||
class="md:flex md:px-5 md:space-x-10 md:justify-between md:items-center"
|
||||
>
|
||||
<GameTitleLine :path="thisGame.icon" :title="thisGame.name" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md:w-1/2 grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<BaseButton
|
||||
v-if="!thisGame.noScores"
|
||||
:href="`/#/games/${gameID}/scores`"
|
||||
:icon="mdiPlaylistMusicOutline"
|
||||
:outline="false"
|
||||
color="info"
|
||||
label="Network Scores"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="!thisGame.noRecords"
|
||||
:href="`/#/games/${gameID}/records`"
|
||||
:icon="mdiFormatListText"
|
||||
:outline="false"
|
||||
color="info"
|
||||
label="Network Records"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SectionTitleLine :icon="mdiAccountMultiple" title="All Players" main />
|
||||
<CardBox has-table>
|
||||
<div
|
||||
class="bg-white dark:bg-slate-900/95 rounded-2xl lg:flex lg:justify-between"
|
||||
>
|
||||
<div class="w-full">
|
||||
<GeneralTable
|
||||
:headers="headers"
|
||||
:items="profiles"
|
||||
:path="`/#/${gameID}/profiles/`"
|
||||
@row-clicked="navigateToProfile"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardBox>
|
||||
</SectionMain>
|
||||
</LayoutAuthenticated>
|
||||
</template>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { reactive, watch, ref, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { mdiSwordCross, mdiPlus } from "@mdi/js";
|
||||
import { PhSword, PhPlusCircle } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
|
|
@ -133,13 +133,12 @@ function filterProfiles() {
|
|||
:game="gameID"
|
||||
:version="versionForm.currentVersion"
|
||||
:profile="profile"
|
||||
use-small
|
||||
>
|
||||
</ProfileCard>
|
||||
</div>
|
||||
</GameHeader>
|
||||
|
||||
<SectionTitleLine :icon="mdiPlus" title="Add a Rival" main />
|
||||
<SectionTitleLine :icon="PhPlusCircle" title="Add a Rival" main />
|
||||
<CardBox v-if="versionForm.currentVersion" class="mb-6">
|
||||
<FormField
|
||||
label="Search"
|
||||
|
|
@ -180,7 +179,7 @@ function filterProfiles() {
|
|||
</div>
|
||||
</CardBox>
|
||||
|
||||
<SectionTitleLine :icon="mdiSwordCross" title="Rivals" main />
|
||||
<SectionTitleLine :icon="PhSword" title="Rivals" main />
|
||||
<CardBox v-if="versionForm.currentVersion" class="mb-6">
|
||||
<div class="grid gap-3">
|
||||
<CardBox v-for="rival of profile?.rivals" :key="rival.id">
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
<script setup>
|
||||
import { reactive, ref, onMounted, computed } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import {
|
||||
mdiPlaylistMusic,
|
||||
mdiFormatListBulleted,
|
||||
mdiFormatListNumbered,
|
||||
} from "@mdi/js";
|
||||
import { PhMusicNote, PhRanking, PhMedal } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
|
|
@ -185,7 +181,7 @@ const navigateToProfile = (item) => {
|
|||
<LayoutAuthenticated>
|
||||
<SectionMain v-if="songData">
|
||||
<GameHeader :game="thisGame" />
|
||||
<SectionTitleLine :icon="mdiPlaylistMusic" title="Song Overview" main />
|
||||
<SectionTitleLine :icon="PhMusicNote" title="Song Overview" main />
|
||||
<CardBox class="mb-6" has-table>
|
||||
<div class="grid gap-4 bg-slate-900/90 card-content">
|
||||
<div>
|
||||
|
|
@ -208,11 +204,7 @@ const navigateToProfile = (item) => {
|
|||
</div>
|
||||
</CardBox>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiFormatListNumbered"
|
||||
title="Top Records"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhRanking" title="Top Records" main />
|
||||
<div class="grid grid-cols-2 lg:grid-cols-5 gap-4 mb-6">
|
||||
<template v-for="chart of songData.charts" :key="chart.db_id">
|
||||
<CardBoxWidget
|
||||
|
|
@ -231,11 +223,7 @@ const navigateToProfile = (item) => {
|
|||
</div>
|
||||
|
||||
<div class="flex place-content-between mb-2">
|
||||
<SectionTitleLine
|
||||
:icon="mdiFormatListBulleted"
|
||||
title="All Scores"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhMedal" title="All Scores" main />
|
||||
<div class="md:w-1/3 md:text-right">
|
||||
<h2 class="text-md sm:text-lg md:text-xl font-bold p-2">
|
||||
Select Chart
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
<script setup>
|
||||
import { computed, ref, onMounted } from "vue";
|
||||
import {
|
||||
mdiGamepad,
|
||||
mdiNewspaperVariant,
|
||||
mdiChartTimelineVariant,
|
||||
mdiCounter,
|
||||
mdiGamepadOutline,
|
||||
mdiFire,
|
||||
mdiTrendingUp,
|
||||
} from "@mdi/js";
|
||||
PhJoystick,
|
||||
PhNewspaper,
|
||||
PhTrendUp,
|
||||
PhPlay,
|
||||
PhFire,
|
||||
PhMedal,
|
||||
PhRanking,
|
||||
} from "@phosphor-icons/vue";
|
||||
import UserCard from "@/components/UserCard.vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -159,56 +159,56 @@ const todayPlays = computed(() => {
|
|||
const cardBoxes = ref([
|
||||
{
|
||||
label: "Cumulative Plays",
|
||||
icon: mdiCounter,
|
||||
icon: PhPlay,
|
||||
iconColor: "text-emerald-600",
|
||||
suffix: "play",
|
||||
number: cumulativePlays,
|
||||
},
|
||||
{
|
||||
label: "Games Played",
|
||||
icon: mdiGamepadOutline,
|
||||
icon: PhJoystick,
|
||||
iconColor: "text-sky-300",
|
||||
suffix: "game",
|
||||
number: uniqueProfiles,
|
||||
},
|
||||
{
|
||||
label: "Plays Today",
|
||||
icon: mdiCounter,
|
||||
icon: PhPlay,
|
||||
iconColor: "text-sky-300",
|
||||
suffix: "play",
|
||||
number: todayPlays,
|
||||
},
|
||||
{
|
||||
label: "Longest Play Streak",
|
||||
icon: mdiFire,
|
||||
icon: PhFire,
|
||||
iconColor: "text-red-500",
|
||||
suffix: "play",
|
||||
number: longestStreak,
|
||||
},
|
||||
{
|
||||
label: "Total Records",
|
||||
icon: mdiGamepadOutline,
|
||||
iconColor: "text-sky-300",
|
||||
icon: PhRanking,
|
||||
iconColor: "text-amber-400",
|
||||
suffix: "record",
|
||||
number: totalRecords,
|
||||
},
|
||||
{
|
||||
label: "Total Attempts",
|
||||
icon: mdiGamepadOutline,
|
||||
iconColor: "text-sky-300",
|
||||
icon: PhMedal,
|
||||
iconColor: "text-pink-300",
|
||||
suffix: "attempt",
|
||||
number: totalAttempts,
|
||||
},
|
||||
{
|
||||
label: "Records Today",
|
||||
icon: mdiGamepadOutline,
|
||||
iconColor: "text-sky-300",
|
||||
icon: PhRanking,
|
||||
iconColor: "text-amber-400",
|
||||
suffix: "record",
|
||||
number: todayRecords,
|
||||
},
|
||||
{
|
||||
label: "Attempts Today",
|
||||
icon: mdiGamepadOutline,
|
||||
icon: PhMedal,
|
||||
iconColor: "text-sky-300",
|
||||
suffix: "attempt",
|
||||
number: todayAttempts,
|
||||
|
|
@ -221,8 +221,7 @@ const cardBoxes = ref([
|
|||
<SectionMain>
|
||||
<UserCard class="mb-6 mt-2 shadow-xl" />
|
||||
|
||||
<SectionTitleLine :icon="mdiNewspaperVariant" title="Network News" main />
|
||||
|
||||
<SectionTitleLine :icon="PhNewspaper" title="Network News" main />
|
||||
<div
|
||||
v-if="newsData.length"
|
||||
class="grid gap-4 grid-cols-1 xl:grid-cols-2 w-full pb-4"
|
||||
|
|
@ -245,11 +244,7 @@ const cardBoxes = ref([
|
|||
</div>
|
||||
<CardBoxComponentEmpty v-if="!newsData || !newsData.length" />
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiChartTimelineVariant"
|
||||
title="Quick Stats"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhTrendUp" title="Quick Stats" main />
|
||||
<div
|
||||
class="grid grid-cols-2 sm:grid-cols-3 gap-6 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 3xl:grid-cols-5 mb-6"
|
||||
>
|
||||
|
|
@ -265,7 +260,7 @@ const cardBoxes = ref([
|
|||
</template>
|
||||
</div>
|
||||
|
||||
<SectionTitleLine :icon="mdiGamepad" title="Showcase" main />
|
||||
<SectionTitleLine :icon="PhJoystick" title="Showcase" main />
|
||||
<div
|
||||
class="grid grid-flow-row auto-rows-auto grid-cols-2 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-3 3xl:grid-cols-4 4xl:grid-cols-6 gap-5 mb-5"
|
||||
>
|
||||
|
|
@ -279,7 +274,7 @@ const cardBoxes = ref([
|
|||
/>
|
||||
</div>
|
||||
|
||||
<SectionTitleLine :icon="mdiTrendingUp" title="Play Trends" main />
|
||||
<SectionTitleLine :icon="PhTrendUp" title="Play Trends" main />
|
||||
<CardBox class="mb-6">
|
||||
<div v-if="userProfiles">
|
||||
<LineChart
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { mdiNewspaperVariant } from "@mdi/js";
|
||||
import { PhNewspaper } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
|
|
@ -29,7 +29,7 @@ function humanReadableTime(timestamp) {
|
|||
<template>
|
||||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<SectionTitleLine :icon="mdiNewspaperVariant" title="Network News" main />
|
||||
<SectionTitleLine :icon="PhNewspaper" title="Network News" main />
|
||||
|
||||
<div class="grid gap-4 grid-cols-1 w-full">
|
||||
<CardBoxNews
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { mdiBackburger } from "@mdi/js";
|
||||
import { PhCaretDoubleLeft } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -71,7 +71,7 @@ function goBack() {
|
|||
<BaseButton
|
||||
label="Home"
|
||||
color="info"
|
||||
:icon="mdiBackburger"
|
||||
:icon="PhCaretDoubleLeft"
|
||||
icon-size="20"
|
||||
@click="goBack"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
<script setup>
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import {
|
||||
mdiCardAccountDetailsOutline,
|
||||
mdiCreditCardPlusOutline,
|
||||
mdiCreditCardEditOutline,
|
||||
} from "@mdi/js";
|
||||
PhIdentificationCard,
|
||||
PhPlusCircle,
|
||||
PhCreditCard,
|
||||
PhSpinnerBall,
|
||||
} from "@phosphor-icons/vue";
|
||||
import { dashCode } from "@/constants/userData.js";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
|
|
@ -86,11 +87,7 @@ const copyToClipboard = (text) => {
|
|||
<SectionMain>
|
||||
<UserCard class="mb-6" use-small even-smaller />
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiCreditCardPlusOutline"
|
||||
title="Add a Card"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhPlusCircle" title="Add a Card" main />
|
||||
<CardBox is-form class="row-span-2 mb-6" @submit.prevent="submitCard()">
|
||||
<FormField
|
||||
label="Card ID"
|
||||
|
|
@ -98,7 +95,7 @@ const copyToClipboard = (text) => {
|
|||
>
|
||||
<FormControl
|
||||
v-model="cardForm.newCard"
|
||||
:icon="mdiCreditCardEditOutline"
|
||||
:icon="PhCreditCard"
|
||||
name="cardId"
|
||||
type="card"
|
||||
placeholder="XXXX-XXXX-XXXX-XXXX"
|
||||
|
|
@ -113,7 +110,7 @@ const copyToClipboard = (text) => {
|
|||
<BaseButton type="submit" color="success" label="Add" />
|
||||
<BaseIcon
|
||||
v-if="cardLoading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
@ -122,7 +119,7 @@ const copyToClipboard = (text) => {
|
|||
|
||||
<div class="grid md:grid-cols-2 mb-2">
|
||||
<SectionTitleLine
|
||||
:icon="mdiCardAccountDetailsOutline"
|
||||
:icon="PhIdentificationCard"
|
||||
title="Login Cards"
|
||||
main
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import {
|
||||
mdiAccountArrowLeftOutline,
|
||||
mdiCreditCardEditOutline,
|
||||
mdiAsterisk,
|
||||
mdiCardAccountDetails,
|
||||
mdiLoading,
|
||||
mdiAccountConvertOutline,
|
||||
} from "@mdi/js";
|
||||
PhUserCircleDashed,
|
||||
PhCreditCard,
|
||||
PhPassword,
|
||||
PhUserSwitch,
|
||||
PhSpinnerBall,
|
||||
PhUnite,
|
||||
} from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
|
|
@ -132,11 +132,7 @@ async function saveSettings() {
|
|||
<UserCard class="mb-6" use-small even-smaller />
|
||||
|
||||
<template v-if="!takeoverData">
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccountArrowLeftOutline"
|
||||
title="Claim a Profile"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhUserSwitch" title="Claim a Profile" main />
|
||||
<CardBox is-form class="row-span-2 mb-6" @submit.prevent="submitCard()">
|
||||
<h2 class="text-xl mb-6 lg:w-1/2">
|
||||
If you registered a card in game and need to claim it, you may do so
|
||||
|
|
@ -149,7 +145,7 @@ async function saveSettings() {
|
|||
>
|
||||
<FormControl
|
||||
v-model="profileForm.cardId"
|
||||
:icon="mdiCreditCardEditOutline"
|
||||
:icon="PhCreditCard"
|
||||
name="cardId"
|
||||
type="card"
|
||||
placeholder="XXXX-XXXX-XXXX-XXXX"
|
||||
|
|
@ -163,7 +159,7 @@ async function saveSettings() {
|
|||
<FormField label="PIN" help="Used when logging into a game">
|
||||
<FormControl
|
||||
v-model="profileForm.pin"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
type="password"
|
||||
name="pin"
|
||||
:minlength="4"
|
||||
|
|
@ -179,7 +175,7 @@ async function saveSettings() {
|
|||
<BaseButton type="submit" color="success" label="Start Claim" />
|
||||
<BaseIcon
|
||||
v-if="cardLoading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
@ -189,7 +185,7 @@ async function saveSettings() {
|
|||
|
||||
<div v-if="takeoverData && saveState == null">
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccountArrowLeftOutline"
|
||||
:icon="PhUserCircleDashed"
|
||||
title="Select Profiles to Merge"
|
||||
main
|
||||
/>
|
||||
|
|
@ -227,7 +223,7 @@ async function saveSettings() {
|
|||
<FormCheckRadio
|
||||
v-model="mergeSettings.card"
|
||||
:input-value="mergeSettings.card"
|
||||
:icon="mdiCardAccountDetails"
|
||||
:icon="PhCreditCard"
|
||||
type="switch"
|
||||
name="card"
|
||||
/>
|
||||
|
|
@ -245,12 +241,7 @@ async function saveSettings() {
|
|||
</div>
|
||||
|
||||
<div v-if="saveState == true">
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccountConvertOutline"
|
||||
title="Merge Results"
|
||||
main
|
||||
/>
|
||||
|
||||
<SectionTitleLine :icon="PhUnite" title="Merge Results" main />
|
||||
<CardBox>
|
||||
<h2 class="text-xl mb-6">
|
||||
✅ Successfully merged {{ recordCount }} records. Yippie!
|
||||
|
|
@ -263,12 +254,7 @@ async function saveSettings() {
|
|||
</div>
|
||||
|
||||
<div v-if="saveState == false">
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccountConvertOutline"
|
||||
title="Merge Results"
|
||||
main
|
||||
/>
|
||||
|
||||
<SectionTitleLine :icon="PhUnite" title="Merge Results" main />
|
||||
<CardBox>
|
||||
<h2 class="text-xl mb-6">❌ Failed to merge. Please try again.</h2>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { mdiFileUploadOutline } from "@mdi/js";
|
||||
import { PhFileImage } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import GameIcon from "@/components/GameIcon.vue";
|
||||
|
|
@ -57,11 +57,7 @@ function filterContent(data) {
|
|||
<UserCard class="mb-6" use-small even-smaller />
|
||||
|
||||
<template v-if="contentData">
|
||||
<SectionTitleLine
|
||||
:icon="mdiFileUploadOutline"
|
||||
title="Your Uploads"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhFileImage" title="Your Uploads" main />
|
||||
<CardBox
|
||||
v-for="content of contentData"
|
||||
:key="content.timestamp"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { useMainStore } from "@/stores/main";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ref, watch } from "vue";
|
||||
import { mdiAccountTieHat } from "@mdi/js";
|
||||
import { PhPaintBrushBroad } from "@phosphor-icons/vue";
|
||||
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -63,7 +63,7 @@ async function revert() {
|
|||
<SectionMain>
|
||||
<UserCard class="mb-6" />
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccountTieHat"
|
||||
:icon="PhPaintBrushBroad"
|
||||
title="Profile Customizations"
|
||||
main
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { mdiFlagCheckered, mdiFlagOff, mdiFlagOutline } from "@mdi/js";
|
||||
import { PhFlag, PhFlagBannerFold, PhFlagCheckered } from "@phosphor-icons/vue";
|
||||
import { reactive } from "vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
@ -94,7 +94,7 @@ const setGoals = [
|
|||
<template>
|
||||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<SectionTitleLine :icon="mdiFlagOutline" title="Your Goals" main />
|
||||
<SectionTitleLine :icon="PhFlag" title="Your Goals" main />
|
||||
|
||||
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 mb-6">
|
||||
<CardBoxWidget
|
||||
|
|
@ -114,14 +114,14 @@ const setGoals = [
|
|||
/>
|
||||
</div>
|
||||
|
||||
<SectionTitleLine :icon="mdiFlagCheckered" title="Active Goals" />
|
||||
<SectionTitleLine :icon="PhFlagCheckered" title="Active Goals" />
|
||||
<div class="mb-6">
|
||||
<CardBox has-table>
|
||||
<TableGoals :goals="setGoals" />
|
||||
</CardBox>
|
||||
</div>
|
||||
|
||||
<SectionTitleLine :icon="mdiFlagOff" title="Past Goals" />
|
||||
<SectionTitleLine :icon="PhFlagBannerFold" title="Past Goals" />
|
||||
<div class="mb-12">
|
||||
<CardBox has-table>
|
||||
<TableGoals :goals="setGoals" is-past />
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { useMainStore } from "@/stores/main";
|
||||
import { ref, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { mdiServerNetwork, mdiMessage, mdiScoreboard } from "@mdi/js";
|
||||
import { PhCloud, PhDiscordLogo, PhRanking } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
|
|
@ -42,7 +42,7 @@ const services = [
|
|||
{
|
||||
id: "discord",
|
||||
name: "Discord",
|
||||
icon: mdiMessage,
|
||||
icon: PhDiscordLogo,
|
||||
oAuth: DISCORD_OAUTH_URL,
|
||||
description:
|
||||
"Linking your Discord account to PhaseII gives you an avatar, enables push notifications, and more via our Discord bot, BadManiac.\n\nPhaseII *does not* use Discord's API aside from the initial linkage. All data PhaseII uses is sent via our bot.\n\nNo data aside from your avatar, User ID, and name is saved.\n\nWe do not save a token nor a cookie.",
|
||||
|
|
@ -50,7 +50,7 @@ const services = [
|
|||
{
|
||||
id: "tachi",
|
||||
name: "Kamaitachi",
|
||||
icon: mdiScoreboard,
|
||||
icon: PhRanking,
|
||||
oAuth: TACHI_OAUTH_URL,
|
||||
description:
|
||||
"Kamaitachi is an open source score tracker using standardized schemas.\n\nLinking Kamaitachi to PhaseII will enable the uploading of all supported scores to Kamaitachi directly, with no user intervention.\n\nYou must follow all rules of Kamaitachi. Failure to adhere to rules will not only put your Kamaitachi account at risk, but also your PhaseII account.\n\nCurrently supported games:\n- DDR\n- IIDX\n- SDVX\n- pop'n (some versions)\n- jubeat",
|
||||
|
|
@ -91,12 +91,8 @@ async function integrateWith(service, code) {
|
|||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<UserCard class="mb-6" use-small even-smaller />
|
||||
<SectionTitleLine
|
||||
:icon="mdiServerNetwork"
|
||||
title="Server Integrations"
|
||||
main
|
||||
/>
|
||||
|
||||
<SectionTitleLine :icon="PhCloud" title="Service Integrations" main />
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<CardBox v-for="service of services" :key="service.id">
|
||||
<PillTag
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
APIGetUserSessions,
|
||||
APIDeleteUserSessions,
|
||||
} from "@/stores/api/account";
|
||||
import { mdiAccount, mdiMail, mdiAsterisk, mdiLoading } from "@mdi/js";
|
||||
import { PhUser, PhAt, PhPassword, PhSpinnerBall } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import BaseDivider from "@/components/BaseDivider.vue";
|
||||
|
|
@ -137,7 +137,7 @@ function userChanged(oldProfile, newProfile) {
|
|||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<UserCard class="mb-6" use-small even-smaller />
|
||||
<SectionTitleLine :icon="mdiAccount" title="Profile Settings" main />
|
||||
<SectionTitleLine :icon="PhUser" title="Profile Settings" main />
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<CardBox is-form class="row-span-1" @submit.prevent="submitProfile">
|
||||
|
|
@ -145,7 +145,7 @@ function userChanged(oldProfile, newProfile) {
|
|||
<FormField label="Username">
|
||||
<FormControl
|
||||
v-model="profileForm.username"
|
||||
:icon="mdiAccount"
|
||||
:icon="PhUser"
|
||||
name="username"
|
||||
required
|
||||
autocomplete="username"
|
||||
|
|
@ -154,7 +154,7 @@ function userChanged(oldProfile, newProfile) {
|
|||
<FormField label="E-mail" help="Used for password resetting and 2FA">
|
||||
<FormControl
|
||||
v-model="profileForm.email"
|
||||
:icon="mdiMail"
|
||||
:icon="PhAt"
|
||||
type="email"
|
||||
name="email"
|
||||
required
|
||||
|
|
@ -165,7 +165,7 @@ function userChanged(oldProfile, newProfile) {
|
|||
<FormField label="PIN" help="Used when logging into a game">
|
||||
<FormControl
|
||||
v-model="profileForm.pin"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
type="password"
|
||||
name="pin"
|
||||
:minlength="4"
|
||||
|
|
@ -199,7 +199,7 @@ function userChanged(oldProfile, newProfile) {
|
|||
/>
|
||||
<BaseIcon
|
||||
v-if="profileLoading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
@ -211,7 +211,7 @@ function userChanged(oldProfile, newProfile) {
|
|||
<FormField label="Current Password">
|
||||
<FormControl
|
||||
v-model="passwordForm.currentPassword"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
name="currentPassword"
|
||||
type="password"
|
||||
required
|
||||
|
|
@ -222,7 +222,7 @@ function userChanged(oldProfile, newProfile) {
|
|||
<FormField label="New Password">
|
||||
<FormControl
|
||||
v-model="passwordForm.newPassword"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
name="newPassword"
|
||||
type="password"
|
||||
required
|
||||
|
|
@ -232,7 +232,7 @@ function userChanged(oldProfile, newProfile) {
|
|||
<FormField label="Confirm Password">
|
||||
<FormControl
|
||||
v-model="passwordForm.confirmPassword"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
name="confirmPassword"
|
||||
type="password"
|
||||
required
|
||||
|
|
@ -243,7 +243,7 @@ function userChanged(oldProfile, newProfile) {
|
|||
<BaseButton type="submit" color="success" label="Update" />
|
||||
<BaseIcon
|
||||
v-if="passwordLoading"
|
||||
:path="mdiLoading"
|
||||
:icon="PhSpinnerBall"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -2,18 +2,18 @@
|
|||
import { computed, ref, reactive, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import {
|
||||
mdiAccount,
|
||||
mdiGamepad,
|
||||
mdiChartTimelineVariant,
|
||||
mdiCounter,
|
||||
mdiGamepadOutline,
|
||||
mdiFire,
|
||||
mdiTrendingUp,
|
||||
mdiShieldEditOutline,
|
||||
mdiInformationOutline,
|
||||
mdiMail,
|
||||
mdiAsterisk,
|
||||
} from "@mdi/js";
|
||||
PhUser,
|
||||
PhJoystick,
|
||||
PhTrendUp,
|
||||
PhPlay,
|
||||
PhFire,
|
||||
PhMedal,
|
||||
PhRanking,
|
||||
PhUserGear,
|
||||
PhInfo,
|
||||
PhAt,
|
||||
PhPassword,
|
||||
} from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import CardBoxWidget from "@/components/CardBoxWidget.vue";
|
||||
|
|
@ -183,56 +183,56 @@ const todayPlays = computed(() => {
|
|||
const cardBoxes = ref([
|
||||
{
|
||||
label: "Cumulative Plays",
|
||||
icon: mdiCounter,
|
||||
icon: PhPlay,
|
||||
iconColor: "text-emerald-600",
|
||||
suffix: "play",
|
||||
number: cumulativePlays,
|
||||
},
|
||||
{
|
||||
label: "Games Played",
|
||||
icon: mdiGamepadOutline,
|
||||
icon: PhJoystick,
|
||||
iconColor: "text-sky-300",
|
||||
suffix: "game",
|
||||
number: uniqueProfiles,
|
||||
},
|
||||
{
|
||||
label: "Plays Today",
|
||||
icon: mdiCounter,
|
||||
icon: PhPlay,
|
||||
iconColor: "text-sky-300",
|
||||
suffix: "play",
|
||||
number: todayPlays,
|
||||
},
|
||||
{
|
||||
label: "Longest Play Streak",
|
||||
icon: mdiFire,
|
||||
icon: PhFire,
|
||||
iconColor: "text-red-500",
|
||||
suffix: "play",
|
||||
number: longestStreak,
|
||||
},
|
||||
{
|
||||
label: "Total Records",
|
||||
icon: mdiGamepadOutline,
|
||||
iconColor: "text-sky-300",
|
||||
icon: PhRanking,
|
||||
iconColor: "text-amber-400",
|
||||
suffix: "record",
|
||||
number: totalRecords,
|
||||
},
|
||||
{
|
||||
label: "Total Attempts",
|
||||
icon: mdiGamepadOutline,
|
||||
iconColor: "text-sky-300",
|
||||
icon: PhMedal,
|
||||
iconColor: "text-pink-300",
|
||||
suffix: "attempt",
|
||||
number: totalAttempts,
|
||||
},
|
||||
{
|
||||
label: "Records Today",
|
||||
icon: mdiGamepadOutline,
|
||||
iconColor: "text-sky-300",
|
||||
icon: PhRanking,
|
||||
iconColor: "text-amber-400",
|
||||
suffix: "record",
|
||||
number: todayRecords,
|
||||
},
|
||||
{
|
||||
label: "Attempts Today",
|
||||
icon: mdiGamepadOutline,
|
||||
icon: PhMedal,
|
||||
iconColor: "text-sky-300",
|
||||
suffix: "attempt",
|
||||
number: todayAttempts,
|
||||
|
|
@ -284,7 +284,7 @@ const openArcade = (item) => {
|
|||
<SectionMain>
|
||||
<template v-if="userProfile !== null">
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccount"
|
||||
:icon="PhUser"
|
||||
:title="`${userProfile.name}'s Profile`"
|
||||
main
|
||||
/>
|
||||
|
|
@ -292,7 +292,7 @@ const openArcade = (item) => {
|
|||
|
||||
<template v-if="mainStore.userAdmin">
|
||||
<SectionTitleLine
|
||||
:icon="mdiShieldEditOutline"
|
||||
:icon="PhUserGear"
|
||||
title="User Administration"
|
||||
main
|
||||
/>
|
||||
|
|
@ -301,7 +301,7 @@ const openArcade = (item) => {
|
|||
<PillTag
|
||||
color="info"
|
||||
label="General Information"
|
||||
:icon="mdiInformationOutline"
|
||||
:icon="PhInfo"
|
||||
class="mb-2"
|
||||
/>
|
||||
<div class="grid md:grid-cols-2 gap-x-4 mb-6">
|
||||
|
|
@ -320,7 +320,7 @@ const openArcade = (item) => {
|
|||
>
|
||||
<FormControl
|
||||
v-model="newUser.email"
|
||||
:icon="mdiMail"
|
||||
:icon="PhAt"
|
||||
type="email"
|
||||
name="email"
|
||||
required
|
||||
|
|
@ -330,7 +330,7 @@ const openArcade = (item) => {
|
|||
<FormField label="PIN" help="Used when logging into a game">
|
||||
<FormControl
|
||||
v-model="newUser.pin"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
type="password"
|
||||
name="pin"
|
||||
:minlength="4"
|
||||
|
|
@ -385,7 +385,7 @@ const openArcade = (item) => {
|
|||
<FormField label="New Password">
|
||||
<FormControl
|
||||
v-model="passwordForm.newPassword"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
name="newPassword"
|
||||
type="password"
|
||||
required
|
||||
|
|
@ -395,7 +395,7 @@ const openArcade = (item) => {
|
|||
<FormField label="Confirm Password">
|
||||
<FormControl
|
||||
v-model="passwordForm.confirmPassword"
|
||||
:icon="mdiAsterisk"
|
||||
:icon="PhPassword"
|
||||
name="confirmPassword"
|
||||
type="password"
|
||||
required
|
||||
|
|
@ -414,7 +414,9 @@ const openArcade = (item) => {
|
|||
:key="arcade.id"
|
||||
class="bg-slate-800 p-4 rounded-xl"
|
||||
>
|
||||
<div class="md:flex w-full place-content-between">
|
||||
<div
|
||||
class="grid grid-cols-1 gap-4 xl:flex w-full place-content-between"
|
||||
>
|
||||
<div>
|
||||
<h1 class="text-md md:text-lg">{{ arcade.name }}</h1>
|
||||
</div>
|
||||
|
|
@ -433,11 +435,7 @@ const openArcade = (item) => {
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="mdiChartTimelineVariant"
|
||||
title="Quick Stats"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhTrendUp" title="Quick Stats" main />
|
||||
<div
|
||||
class="grid grid-cols-2 sm:grid-cols-3 gap-6 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 3xl:grid-cols-5 mb-6"
|
||||
>
|
||||
|
|
@ -453,7 +451,7 @@ const openArcade = (item) => {
|
|||
</template>
|
||||
</div>
|
||||
|
||||
<SectionTitleLine :icon="mdiGamepad" title="Showcase" main />
|
||||
<SectionTitleLine :icon="PhJoystick" title="Showcase" main />
|
||||
<div
|
||||
class="grid grid-flow-row auto-rows-auto grid-cols-2 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-3 3xl:grid-cols-4 4xl:grid-cols-6 gap-5 mb-5"
|
||||
>
|
||||
|
|
@ -468,7 +466,7 @@ const openArcade = (item) => {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<SectionTitleLine :icon="mdiTrendingUp" title="Play Trends" main />
|
||||
<SectionTitleLine :icon="PhTrendUp" title="Play Trends" main />
|
||||
<CardBox class="mb-6">
|
||||
<div v-if="userProfiles">
|
||||
<LineChart
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { mdiVideoOutline, mdiVideoWirelessOutline } from "@mdi/js";
|
||||
import { PhFilmReel, PhVideo } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
|
|
@ -140,11 +140,7 @@ function openInNewTab(url) {
|
|||
<UserCard class="mb-6" use-small even-smaller />
|
||||
|
||||
<template v-if="videoData[0]">
|
||||
<SectionTitleLine
|
||||
:icon="mdiVideoWirelessOutline"
|
||||
title="Your Latest Upload"
|
||||
main
|
||||
/>
|
||||
<SectionTitleLine :icon="PhVideo" title="Your Latest Video" main />
|
||||
<CardBox class="mb-6">
|
||||
<div
|
||||
v-if="videoData[0]?.data?.status == 'uploaded'"
|
||||
|
|
@ -201,8 +197,7 @@ function openInNewTab(url) {
|
|||
</CardBox>
|
||||
</template>
|
||||
|
||||
<SectionTitleLine :icon="mdiVideoOutline" title="All Play Videos" main />
|
||||
|
||||
<SectionTitleLine :icon="PhFilmReel" title="All Play Videos" main />
|
||||
<CardBox has-table>
|
||||
<div
|
||||
class="bg-white dark:bg-slate-900/95 rounded-2xl lg:flex lg:justify-between"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user