feature: added create,join,spectate buttons and create game dialog

This commit is contained in:
Muhammad Sabeeh 2025-06-18 17:17:47 -04:00
parent 4b0dff4102
commit 91448e21b1
10 changed files with 265 additions and 112 deletions

View file

@ -2118,6 +2118,19 @@
"node": ">= 8"
}
},
"node_modules/anymatch/node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/archiver": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz",
@ -4666,6 +4679,19 @@
"node": ">=8.6"
}
},
"node_modules/micromatch/node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@ -5148,12 +5174,13 @@
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
@ -5444,6 +5471,19 @@
"node": ">=8.10.0"
}
},
"node_modules/readdirp/node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/relateurl": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
@ -5622,18 +5662,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/rollup-plugin-visualizer/node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/rollup-plugin-visualizer/node_modules/source-map": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
@ -6512,18 +6540,6 @@
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/tinyglobby/node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@ -6630,7 +6646,7 @@
"version": "5.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
"dev": true,
"devOptional": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -6934,18 +6950,6 @@
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/vite-plugin-checker/node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/vite-plugin-checker/node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
@ -6974,18 +6978,6 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/vite/node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/vscode-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
@ -7873,7 +7865,8 @@
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@quasar/vite-plugin/-/vite-plugin-1.9.0.tgz",
"integrity": "sha512-r1MFtI2QZJ2g20pe75Zuv4aoi0uoK8oP0yEdzLWRoOLCbhtf2+StJpUza9TydYi3KcvCl9+4HUf3OAWVKoxDmQ==",
"dev": true
"dev": true,
"requires": {}
},
"@rollup/rollup-android-arm-eabi": {
"version": "4.43.0",
@ -8243,7 +8236,8 @@
"version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.0.tgz",
"integrity": "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==",
"dev": true
"dev": true,
"requires": {}
},
"@typescript-eslint/type-utils": {
"version": "8.34.0",
@ -8315,7 +8309,8 @@
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
"integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==",
"dev": true
"dev": true,
"requires": {}
},
"@volar/language-core": {
"version": "2.4.14",
@ -8521,7 +8516,8 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true
"dev": true,
"requires": {}
},
"ajv": {
"version": "6.12.6",
@ -8581,6 +8577,14 @@
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
},
"dependencies": {
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
}
}
},
"archiver": {
@ -9439,7 +9443,8 @@
"version": "10.1.5",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.5.tgz",
"integrity": "sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==",
"dev": true
"dev": true,
"requires": {}
},
"eslint-plugin-prettier": {
"version": "5.4.1",
@ -9731,7 +9736,8 @@
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
"integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
"dev": true
"dev": true,
"requires": {}
},
"file-entry-cache": {
"version": "8.0.0",
@ -10406,6 +10412,14 @@
"requires": {
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"dependencies": {
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
}
}
},
"mime": {
@ -10756,9 +10770,9 @@
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
},
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true
},
"pkg-types": {
@ -10946,6 +10960,14 @@
"dev": true,
"requires": {
"picomatch": "^2.2.1"
},
"dependencies": {
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
}
}
},
"relateurl": {
@ -11072,12 +11094,6 @@
"is-wsl": "^2.2.0"
}
},
"picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true
},
"source-map": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
@ -11642,14 +11658,6 @@
"requires": {
"fdir": "^6.4.4",
"picomatch": "^4.0.2"
},
"dependencies": {
"picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true
}
}
},
"tmp": {
@ -11680,13 +11688,15 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
"dev": true
"dev": true,
"requires": {}
},
"ts-essentials": {
"version": "9.4.2",
"resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-9.4.2.tgz",
"integrity": "sha512-mB/cDhOvD7pg3YCLk2rOtejHjjdSi9in/IBYE13S+8WA5FBSraYf4V/ws55uvs0IvQ/l0wBOlXy5yBNZ9Bl8ZQ==",
"dev": true
"dev": true,
"requires": {}
},
"tslib": {
"version": "2.8.1",
@ -11723,7 +11733,7 @@
"version": "5.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
"dev": true
"devOptional": true
},
"typescript-eslint": {
"version": "8.34.0",
@ -11822,14 +11832,6 @@
"postcss": "^8.5.3",
"rollup": "^4.34.9",
"tinyglobby": "^0.2.13"
},
"dependencies": {
"picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true
}
}
},
"vite-plugin-checker": {
@ -11864,12 +11866,6 @@
"readdirp": "^4.0.1"
}
},
"picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true
},
"readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",

View file

@ -14,7 +14,7 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import type { Todo, Meta } from './models';
import type { Todo, Meta } from '../models/models';
interface Props {
title: string;

View file

@ -1,8 +0,0 @@
export interface Todo {
id: number;
content: string;
}
export interface Meta {
totalCount: number;
}

View file

@ -0,0 +1,16 @@
const gameTypes = [
'Standard',
'Pioneer',
'Modern',
'Legacy',
'Vintage',
'Limited',
'Commander',
'Highlander',
'Pre-Modern',
'Old School',
'Pauper',
'Other',
]
export default gameTypes;

View file

@ -1,14 +1,5 @@
import type { QTableProps } from 'quasar';
interface Games {
age: string;
description: string;
creator: string;
type: string;
restrictions: string;
players: string;
spectators: string | number;
}
import type { Games } from 'src/models/models';
const restrictions = ['🔒 password', 'reg. users only', 'buddies only'];

View file

@ -0,0 +1,19 @@
export interface Todo {
id: number;
content: string;
}
export interface Meta {
totalCount: number;
}
export interface Games {
age: string;
description: string;
creator: string;
type: string;
restrictions: string;
players: string;
spectators: string | number;
}

View file

@ -0,0 +1,3 @@
<template>
<p>HELLO</p>
</template>

View file

@ -10,7 +10,101 @@
virtual-scroll
:pagination-label="(start, end, total) => `Total games: ${total}`"
style="height: 60%"
@row-click="
(evt, row, index) => {
console.log('Row clicked:', row);
selectedGame = row;
}
"
/>
<div class="flex justify-end q-mt-md">
<div class="row q-pa-sm q-gutter-sm">
<q-btn outline label="Create" color="primary" @click="createGameDialog = true" />
<!-- @click="redirectGame" -->
<q-btn outline label="Join" color="secondary" :disable="selectedGame ? false : true" />
<q-btn outline label="Join as Spectator" :disable="selectedGame ? false : true" />
</div>
</div>
<q-dialog v-model="createGameDialog" persistent>
<q-card style="min-width: 350px">
<q-card-section class="row items-center bg-primary">
<CockatriceAvatar square size="25px" />
<div class="flex justify-between text-h6" style="color: white; width: 100%">
<div>Create game</div>
<q-btn icon="close" flat round dense v-close-popup />
</div>
</q-card-section>
<q-card-section class="row justify-center q-pa-md q-gutter-md">
<!-- COLUMN 1 -->
<div class="col q-gutter-sm">
<q-input
filled
label="Description"
label-color="primary"
v-model="newGameDesc"
autofocus
/>
<q-input
filled
label="Players"
type="number"
label-color="primary"
v-model="newGamePlayers"
autofocus
/>
<q-select
filled
label="Game Type"
label-color="primary"
v-model="newGameType"
:options="gameTypes"
/>
<div>
<q-input
filled
label="Life Total"
type="number"
label-color="primary"
v-model="newGameLifeTotal"
/>
</div>
</div>
<!-- COLUMN 2 -->
<div class="col q-gutter-sm">
<q-input
filled
label="Password"
type="password"
label-color="primary"
v-model="newGamePassword"
autofocus
/>
<q-checkbox label="Only buddies can join" v-model="newGameOnlyBuddies" />
<q-checkbox label="Only registered users can join" v-model="newGameOnlyRegistered" />
<q-checkbox label="Spectators can watch" v-model="newGameSpectatorsCanWatch" />
<q-checkbox
label="Spectators need a password to watch"
v-model="newGameSpectatorsNeedPassword"
/>
<q-checkbox label="Spectators can chat" v-model="newGameSpectatorsCanChat" />
<q-checkbox label="Spectators can see hands" v-model="newGameSpectatorsCanSeeHands" />
<q-checkbox label="Create game as Spectator" v-model="newGameAsSpectator" />
</div>
</q-card-section>
<q-card-actions align="right" class="text-primary">
<q-btn flat label="OK" @click="redirectGame" />
<q-btn flat label="Clear" />
<q-btn flat label="CANCEL" @click="createGameDialog = false" />
</q-card-actions>
</q-card>
<!-- END OF LOGIN -->
</q-dialog>
<q-card style="height: 30%" class="q-mt-md">
<q-list bordered separator>
@ -38,7 +132,42 @@
<script setup lang="ts">
import userBadge from 'assets/pawn_single.svg';
import { games, gameColumns } from 'src/fake-data/gameColumns';
import type { Games } from 'src/models/models';
import { chats } from 'src/fake-data/chats';
import { useRouter } from 'vue-router';
import { ref } from 'vue';
import gameTypes from 'src/constants/gametypes';
const selectedGame = ref<Games | null>(null);
const createGameDialog = ref(false);
const newGameDesc = ref(''); // Default description for new game
const newGamePlayers = ref(4); // Default to 4 players
//join restrictions
const newGamePassword = ref(''); // Default empty password
const newGameOnlyBuddies = ref(false); // Default to false
const newGameOnlyRegistered = ref(false); // Default to false
//game types
const newGameType = ref(gameTypes[7]); // Default empty game type
//spectators
const newGameSpectatorsCanWatch = ref(false); // Default to false
const newGameSpectatorsNeedPassword = ref(false); // Default to false
const newGameSpectatorsCanChat = ref(false); // Default empty password for spectators
const newGameSpectatorsCanSeeHands = ref(false); // Default to false
const newGameAsSpectator = ref(false); // Default to false
// // Game setup options
const newGameLifeTotal = ref(40); // Default life total
const router = useRouter();
async function redirectGame() {
console.log('Redirecting to game...');
await router.push({ name: 'game' });
}
</script>
<style scoped>

View file

@ -12,6 +12,12 @@ const routes: RouteRecordRaw[] = [
component: () => import('layouts/MainLayout.vue'),
children: [{ path: 'home', name: 'home', component: () => import('pages/HomePage.vue') }],
},
{
path: '/',
name: '',
component: () => import('layouts/MainLayout.vue'),
children: [{ path: 'game', name: 'game', component: () => import('pages/GamePage.vue') }],
},
// Always leave this as last one,
// but you can also remove it

1
webclientvue/version.txt Normal file
View file

@ -0,0 +1 @@
Version: "1.0.0"