mirror of
https://github.com/BlossomiShymae/clean-cuts.git
synced 2025-12-06 10:10:47 +01:00
Init commit
This commit is contained in:
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Nuxt dev/build outputs
|
||||||
|
.output
|
||||||
|
.data
|
||||||
|
.nuxt
|
||||||
|
.nitro
|
||||||
|
.cache
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Node dependencies
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
.DS_Store
|
||||||
|
.fleet
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Local env files
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "public/lib/MaterialDesign"]
|
||||||
|
path = public/lib/MaterialDesign
|
||||||
|
url = git@github.com:Templarian/MaterialDesign.git
|
||||||
73
README.md
Normal file
73
README.md
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# Clean Cuts
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Make sure to install the dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn install
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Server
|
||||||
|
|
||||||
|
Start the development server on `http://localhost:3000`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm run dev
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn dev
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production
|
||||||
|
|
||||||
|
Build the application for production:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm run build
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun run build
|
||||||
|
```
|
||||||
|
|
||||||
|
Locally preview production build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run preview
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm run preview
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn preview
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun run preview
|
||||||
|
```
|
||||||
27
app.vue
Normal file
27
app.vue
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<NuxtLayout>
|
||||||
|
<NuxtPage keepalive />
|
||||||
|
</NuxtLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.page-enter-active,
|
||||||
|
.page-leave-active {
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
.page-enter-from,
|
||||||
|
.page-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
filter: blur(0.125rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-enter-active,
|
||||||
|
.layout-leave-active {
|
||||||
|
transform: none;
|
||||||
|
transition: all 0.5s;
|
||||||
|
}
|
||||||
|
.layout-enter-from,
|
||||||
|
.layout-leave-to {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
18
components/Badge.vue
Normal file
18
components/Badge.vue
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<template>
|
||||||
|
<span class="badge text-bg-dark border text-dark-emphasis fw-normal d-flex align-items-center gap-2 bg-transparent bg-blur-4 border-light border-opacity-25">
|
||||||
|
<MaterialIcon :size="24" :name="name" />
|
||||||
|
<slot></slot>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import MaterialIcon from './MaterialIcon.vue';
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
name: string
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
19
components/MaterialIcon.vue
Normal file
19
components/MaterialIcon.vue
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<template>
|
||||||
|
<svg :width="size" :height="size">
|
||||||
|
<image :href="`/lib/MaterialDesign/svg/${name}.svg`"
|
||||||
|
:width="size"
|
||||||
|
:height="size"/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
name: string,
|
||||||
|
size: number
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
41
components/Pagination.vue
Normal file
41
components/Pagination.vue
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<div class="btn-group">
|
||||||
|
<NuxtLink :class="`btn btn-outline-dark ${hasFurtherPreviousCss}`">
|
||||||
|
<MaterialIcon name="chevron-double-left" :size="32" />
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink :class="`btn btn-outline-dark ${hasPreviousCss}`">
|
||||||
|
<MaterialIcon name="chevron-left" :size="32" />
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink :class="`btn btn-outline-dark text-light`">
|
||||||
|
{{ pageIndex / totalPages }}
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink :class="`btn btn-outline-dark ${hasNextCss}`">
|
||||||
|
<MaterialIcon name="chevron-right" :size="32" />
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink :class="`btn btn-outline-dark ${hasFurtherNextCss}`">
|
||||||
|
<MaterialIcon name="chevron-double-right" :size="32" />
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import MaterialIcon from './MaterialIcon.vue';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
hasPrevious: boolean;
|
||||||
|
hasFurtherPrevious: boolean;
|
||||||
|
hasNext: boolean;
|
||||||
|
hasFurtherNext: boolean;
|
||||||
|
pageIndex: number;
|
||||||
|
totalPages: number;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const hasPreviousCss = !props.hasPrevious ? "disabled" : "";
|
||||||
|
const hasFurtherPreviousCss = !props.hasFurtherPrevious ? "disabled" : "";
|
||||||
|
const hasNextCss = !props.hasNext ? "disabled" : "";
|
||||||
|
const hasFurtherNextCss = !props.hasFurtherNext ? "disabled" : "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
3
components/TheTitle.vue
Normal file
3
components/TheTitle.vue
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<span>Clean Cuts</span>
|
||||||
|
</template>
|
||||||
9
composables/useClient.ts
Normal file
9
composables/useClient.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Client } from "~/core/client";
|
||||||
|
|
||||||
|
const client = new Client();
|
||||||
|
|
||||||
|
export default function useClient(): { client: Client } {
|
||||||
|
return {
|
||||||
|
client
|
||||||
|
}
|
||||||
|
};
|
||||||
70
core/client.ts
Normal file
70
core/client.ts
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import { ChampionSummary, Item, LocaleVersionArgs, Perk, SummonerEmote, SummonerIcon, WardSkin } from "./models";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export abstract class ApiObject {
|
||||||
|
static url = "https://raw.communitydragon.org";
|
||||||
|
|
||||||
|
getClientPath(args: LocaleVersionArgs): string {
|
||||||
|
return `${ApiObject.url}/${args.version}/plugins/rcp-be-lol-game-data/global/${args.locale}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Client {
|
||||||
|
public items: ItemApi;
|
||||||
|
public perks: PerkApi;
|
||||||
|
public championSummaries: ChampionSummaryApi;
|
||||||
|
public summonerEmotes: SummonerEmoteApi;
|
||||||
|
public summonerIcons: SummonerIconApi;
|
||||||
|
public wardSkins: WardSkinApi;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.items = new ItemApi();
|
||||||
|
this.perks = new PerkApi();
|
||||||
|
this.championSummaries = new ChampionSummaryApi();
|
||||||
|
this.summonerEmotes = new SummonerEmoteApi();
|
||||||
|
this.summonerIcons = new SummonerIconApi();
|
||||||
|
this.wardSkins = new WardSkinApi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ItemApi extends ApiObject {
|
||||||
|
async listAsync(args: LocaleVersionArgs): Promise<Array<Item>> {
|
||||||
|
let res = await axios.get(`${this.getClientPath(args)}/v1/items.json`);
|
||||||
|
return res.data.map((x: any) => new Item(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PerkApi extends ApiObject {
|
||||||
|
async listAsync(args: LocaleVersionArgs): Promise<Array<Perk>> {
|
||||||
|
let res = await axios.get(`${this.getClientPath(args)}/v1/perks.json`);
|
||||||
|
return res.data.map((x: any) => new Perk(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ChampionSummaryApi extends ApiObject {
|
||||||
|
async listAsync(args: LocaleVersionArgs): Promise<Array<ChampionSummary>> {
|
||||||
|
let res = await axios.get(`${this.getClientPath(args)}/v1/champion-summary.json`);
|
||||||
|
return res.data.map((x: any) => new ChampionSummary(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SummonerEmoteApi extends ApiObject {
|
||||||
|
async listAsync(args: LocaleVersionArgs): Promise<Array<SummonerEmote>> {
|
||||||
|
let res = await axios.get(`${this.getClientPath(args)}/v1/summoner-emotes.json`);
|
||||||
|
return res.data.map((x: any) => new SummonerEmote(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SummonerIconApi extends ApiObject {
|
||||||
|
async listAsync(args: LocaleVersionArgs): Promise<Array<SummonerIcon>> {
|
||||||
|
let res = await axios.get(`${this.getClientPath(args)}/v1/summoner-icons.json`);
|
||||||
|
return res.data.map((x: any) => new SummonerEmote(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WardSkinApi extends ApiObject {
|
||||||
|
async listAsync(args: LocaleVersionArgs): Promise<Array<WardSkin>> {
|
||||||
|
let res = await axios.get(`${this.getClientPath(args)}/v1/ward-skins.json`);
|
||||||
|
return res.data.map((x: any) => new WardSkin(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
282
core/models.ts
Normal file
282
core/models.ts
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
|
||||||
|
export class LocaleVersionArgs {
|
||||||
|
locale: string;
|
||||||
|
version: string
|
||||||
|
|
||||||
|
constructor({locale, version}: {locale: string, version: string}) {
|
||||||
|
this.locale = locale;
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class CommunityDragonObject {
|
||||||
|
static url = "https://raw.communitydragon.org";
|
||||||
|
|
||||||
|
resolveClientPath({path, args}: {path: string, args: LocaleVersionArgs}): string {
|
||||||
|
const uri = path.replace("/lol-game-data/assets", "").toLowerCase();
|
||||||
|
return `${CommunityDragonObject.url}/${args.version}/plugins/rcp-be-lol-game-data/global/${args.locale}/${uri}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolveGamePath({path, version}: {path: string, version: string}): string {
|
||||||
|
const uri = path.replace("/lol-game-data/assets/ASSETS/", "").replace(".jpg", ".png").toLowerCase();
|
||||||
|
return `${CommunityDragonObject.url}/${version}/game/assets/${uri}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Champion extends CommunityDragonObject {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
alias: string;
|
||||||
|
title: string;
|
||||||
|
shortBio: string;
|
||||||
|
playstyleInfo: PlaystyleInfo;
|
||||||
|
skins: Array<Skin>;
|
||||||
|
passive: Passive;
|
||||||
|
spells: Array<Spell>;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.id = json.id;
|
||||||
|
this.name = json.name;
|
||||||
|
this.alias = json.alias;
|
||||||
|
this.title = json.title;
|
||||||
|
this.shortBio = json.shortBio;
|
||||||
|
this.playstyleInfo = new PlaystyleInfo(json.playstyleInfo);
|
||||||
|
this.skins = json.skins.map((x: any) => new Skin(x));
|
||||||
|
this.passive = new Passive(json.passive);
|
||||||
|
this.spells = json.spells.map((x: any) => new Spell(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PlaystyleInfo extends CommunityDragonObject {
|
||||||
|
damage: number;
|
||||||
|
durability: number;
|
||||||
|
crowdControl: number;
|
||||||
|
mobility: number;
|
||||||
|
utility: number;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.damage = json.damage;
|
||||||
|
this.durability = json.durability;
|
||||||
|
this.crowdControl = json.crowdControl;
|
||||||
|
this.mobility = json.mobility;
|
||||||
|
this.utility = json.utility;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Skin extends CommunityDragonObject {
|
||||||
|
id: number;
|
||||||
|
isBase: boolean;
|
||||||
|
name: string;
|
||||||
|
rarity: string;
|
||||||
|
isLegacy: boolean;
|
||||||
|
loadScreenPath: string;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.id = json.id;
|
||||||
|
this.isBase = json.isBase;
|
||||||
|
this.name = json.name;
|
||||||
|
this.rarity = json.rarity;
|
||||||
|
this.isLegacy = json.isLegacy;
|
||||||
|
this.loadScreenPath = json.loadScreenPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLoadScreen(version: string): string {
|
||||||
|
return this.resolveGamePath({path: this.loadScreenPath, version: version});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Passive extends CommunityDragonObject {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = json.name;
|
||||||
|
this.description = json.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Spell extends CommunityDragonObject {
|
||||||
|
spellKey: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.spellKey = json.spellKey;
|
||||||
|
this.name = json.name;
|
||||||
|
this.description = json.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ChampionSummary extends CommunityDragonObject {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
alias: string;
|
||||||
|
squarePortraitPath: string;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.id = json.id;
|
||||||
|
this.name = json.name;
|
||||||
|
this.alias = json.alias;
|
||||||
|
this.squarePortraitPath = json.squarePortraitPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
getIcon(args: LocaleVersionArgs): string {
|
||||||
|
return this.resolveClientPath({path: this.squarePortraitPath, args: args});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Item extends CommunityDragonObject {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
active: boolean;
|
||||||
|
inStore: boolean;
|
||||||
|
from: Array<number>;
|
||||||
|
to: Array<number>;
|
||||||
|
categories: Array<number>;
|
||||||
|
price: number;
|
||||||
|
priceTotal: number;
|
||||||
|
iconPath: string;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.id = json.id;
|
||||||
|
this.name = json.name;
|
||||||
|
this.description = json.description;
|
||||||
|
this.active = json.active;
|
||||||
|
this.inStore = json.inStore;
|
||||||
|
this.from = json.from;
|
||||||
|
this.to = json.to;
|
||||||
|
this.categories = json.categories;
|
||||||
|
this.price = json.price;
|
||||||
|
this.priceTotal = json.priceTotal;
|
||||||
|
this.iconPath = json.iconPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
getIcon(version: string): string {
|
||||||
|
return this.resolveGamePath({path: this.iconPath, version: version});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Perk extends CommunityDragonObject {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
shortDesc: string;
|
||||||
|
longDesc: string;
|
||||||
|
iconPath: string;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.id = json.id;
|
||||||
|
this.name = json.name;
|
||||||
|
this.shortDesc = json.shortDesc;
|
||||||
|
this.longDesc = json.longDesc;
|
||||||
|
this.iconPath = json.iconPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
getIcon(version: string): string {
|
||||||
|
return this.resolveClientPath({path: this.iconPath, args: {version: version, locale: "default"}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SummonerEmote extends CommunityDragonObject {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
inventoryIcon: string;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.id = json.id;
|
||||||
|
this.name = json.name;
|
||||||
|
this.inventoryIcon = json.inventoryIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
getInventoryIcon(version: string): string {
|
||||||
|
return this.resolveGamePath({path: this.inventoryIcon, version: version}).replace("inventory", "vfx");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SummonerIcon extends CommunityDragonObject {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
yearReleased: number;
|
||||||
|
isLegacy: boolean;
|
||||||
|
imagePath?: string;
|
||||||
|
descriptions: Array<Description>;
|
||||||
|
rarities: Array<Rarity>;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.id = json.id;
|
||||||
|
this.title = json.title;
|
||||||
|
this.yearReleased = json.yearReleased;
|
||||||
|
this.isLegacy = json.isLegacy;
|
||||||
|
this.imagePath = json.imagePath;
|
||||||
|
this.descriptions = json.descriptions.map((x: any) => new Description(x));
|
||||||
|
this.rarities = json.rarities.map((x: any) => new Rarity(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WardSkin extends CommunityDragonObject {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description : string;
|
||||||
|
wardImagePath: string;
|
||||||
|
wardShadowImagePath: string;
|
||||||
|
isLegacy: boolean;
|
||||||
|
regionDescriptions: Array<Description>;
|
||||||
|
rarities: Array<Rarity>;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.id = json.id;
|
||||||
|
this.name = json.name;
|
||||||
|
this.description = json.description;
|
||||||
|
this.wardImagePath = json.wardImagePath;
|
||||||
|
this.wardShadowImagePath = json.wardShadowImagePath;
|
||||||
|
this.isLegacy = json.isLegacy;
|
||||||
|
this.regionDescriptions = json.regionalDescriptions.map((x: any) => new Description(x));
|
||||||
|
this.rarities = json.rarities.map((x: any) => new Rarity(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Description extends CommunityDragonObject {
|
||||||
|
region: string;
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.region = json.region;
|
||||||
|
this.description = json.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Rarity extends CommunityDragonObject {
|
||||||
|
region: string;
|
||||||
|
rarity: string;
|
||||||
|
|
||||||
|
constructor(json: any) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.region = json.region;
|
||||||
|
this.rarity = json.rarity;
|
||||||
|
}
|
||||||
|
}
|
||||||
128
layouts/default.vue
Normal file
128
layouts/default.vue
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="h-100">
|
||||||
|
<header>
|
||||||
|
<div class="background background-transparent background-blur-2"></div>
|
||||||
|
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light border-bottom border-light border-opacity-25 border-2 box-shadow">
|
||||||
|
<div class="container">
|
||||||
|
<NuxtLink class="navbar-brand fw-light" to="/" ><Title /></NuxtLink>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
||||||
|
aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
|
||||||
|
<ul class="navbar-nav flex-grow-1">
|
||||||
|
<li class="nav-item">
|
||||||
|
<NuxtLink class="nav-link" to="/">
|
||||||
|
<MaterialIcon name="home" :size="24" /> Home
|
||||||
|
</NuxtLink>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<NuxtLink class="nav-link" to="/">
|
||||||
|
<MaterialIcon name="account-group" :size="24" /> Champions
|
||||||
|
</NuxtLink>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<NuxtLink class="nav-link" to="/items">
|
||||||
|
<MaterialIcon name="magic-staff" :size="24" /> Items
|
||||||
|
</NuxtLink>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<NuxtLink class="nav-link" to="/">
|
||||||
|
<MaterialIcon name="shield" :size="24" /> Runes
|
||||||
|
</NuxtLink>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<NuxtLink class="nav-link" to="/">
|
||||||
|
<MaterialIcon name="image" :size="24" /> Summoner Icons
|
||||||
|
</NuxtLink>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<NuxtLink class="nav-link" to="/">
|
||||||
|
<MaterialIcon name="floor-lamp" :size="24" /> Ward Skins
|
||||||
|
</NuxtLink>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<NuxtLink class="nav-link" to="/">
|
||||||
|
<MaterialIcon name="face-woman-shimmer" :size="24" /> Emotes
|
||||||
|
</NuxtLink>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<div class="container">
|
||||||
|
<main role="main" class="pt-3 pb-3">
|
||||||
|
<slot></slot>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="container border border-light border-opacity-25 rounded p-4 pb-2 mt-2 mb-4 bg-blur-4">
|
||||||
|
<div class="d-flex justify-content-around align-items-center gap-2 mb-3 flex-wrap">
|
||||||
|
<NuxtLink class="text-decoration-none text-light" to="about">About</NuxtLink>
|
||||||
|
<a class="text-decoration-none text-light" href="https://challenges.darkintaqt.com" referrerpolicy="no-referrer">Challenge Tracker</a>
|
||||||
|
<a class="text-decoration-none text-light" href="https://blossomishymae.github.io/" referrerpolicy="no-referrer">blossomishymae.github.io</a>
|
||||||
|
<a class="text-decoration-none text-light" href="https://communitydragon.org" referrerpolicy="no-referrer">CommunityDragon</a>
|
||||||
|
<!-- <a class="text-decoration-none text-light" href="https://discord.com/invite/riotgamesdevrel" referrerpolicy="no-referrer">DevRel Discord</a> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-center align-items-center pt-2 border-top border-light border-opacity-25">
|
||||||
|
<p class="text-muted fw-light" style="font-size: 0.8rem;">Peaches was created under Riot Games' "Legal Jibber Jabber" policy using assets owned by Riot Games. Riot Games does not endorse or sponsor this project. </p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MaterialIcon from '~/components/MaterialIcon.vue';
|
||||||
|
import Title from '~/components/Title.vue';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
a.navbar-brand {
|
||||||
|
white-space: normal;
|
||||||
|
text-align: center;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #0077cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #1b6ec2;
|
||||||
|
border-color: #1861ac;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #1b6ec2;
|
||||||
|
border-color: #1861ac;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-top {
|
||||||
|
border-top: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
.border-bottom {
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-shadow {
|
||||||
|
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.accept-policy {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 60px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
62
nuxt.config.ts
Normal file
62
nuxt.config.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import path from "path";
|
||||||
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
|
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
devtools: { enabled: true },
|
||||||
|
nitro: {
|
||||||
|
output: {
|
||||||
|
publicDir: path.join(__dirname, "docs"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
app: {
|
||||||
|
pageTransition: {
|
||||||
|
name: "page",
|
||||||
|
mode: "out-in",
|
||||||
|
},
|
||||||
|
layoutTransition: {
|
||||||
|
name: "layout",
|
||||||
|
mode: "out-in",
|
||||||
|
},
|
||||||
|
head: {
|
||||||
|
htmlAttrs: {
|
||||||
|
"data-bs-theme": "dark",
|
||||||
|
"style": "background-image: url('https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/v1/champion-splashes/498/498004.jpg');"
|
||||||
|
},
|
||||||
|
bodyAttrs: {
|
||||||
|
class: "h-100"
|
||||||
|
},
|
||||||
|
meta: [
|
||||||
|
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
||||||
|
],
|
||||||
|
link: [
|
||||||
|
{
|
||||||
|
rel: "stylesheet",
|
||||||
|
href: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css",
|
||||||
|
integrity:
|
||||||
|
"sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM",
|
||||||
|
crossorigin: "anonymous",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rel: "stylesheet",
|
||||||
|
href: "/css/app.css",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rel: "icon",
|
||||||
|
type: "image/png",
|
||||||
|
href: "/favicon.png",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
script: [
|
||||||
|
{
|
||||||
|
src: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js",
|
||||||
|
integrity:
|
||||||
|
"sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz",
|
||||||
|
crossorigin: "anonymous",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
experimental: {
|
||||||
|
payloadExtraction: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
10647
package-lock.json
generated
Normal file
10647
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
21
package.json
Normal file
21
package.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "nuxt-app",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "nuxt build",
|
||||||
|
"dev": "nuxt dev",
|
||||||
|
"generate": "nuxt generate",
|
||||||
|
"preview": "nuxt preview",
|
||||||
|
"postinstall": "nuxt prepare"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.6.8",
|
||||||
|
"nuxt": "^3.11.2",
|
||||||
|
"vue": "^3.4.21",
|
||||||
|
"vue-router": "^4.3.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"sass": "^1.76.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pages/about.vue
Normal file
53
pages/about.vue
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="d-flex align-items-center flex-column">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h1 class="display-4">About <TheTitle /> </h1>
|
||||||
|
<p class="lead">The <TheTitle /> project was started after experiencing stumbling blocks
|
||||||
|
with a shelved project.
|
||||||
|
</p>
|
||||||
|
<p>Our purpose is to provide League of Legends game data that is easy
|
||||||
|
to view for the common person. This game data is provided by CommunityDragon, another community resource.
|
||||||
|
</p>
|
||||||
|
<p>Therefore, no computer programming or scripting is needed.
|
||||||
|
Not everyone can browse a JSON or navigate game data folders. :3</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 d-flex justify-content-center">
|
||||||
|
<div style="width: 250px !important;" class="d-flex flex-column justify-content-center align-items-center gap-1 border border-light border-opacity-25 bg-blur-3 rounded">
|
||||||
|
<img class="img-fluid rounded mb-2" src="/img/avatar.png"/>
|
||||||
|
<div class="px-3">
|
||||||
|
<div class="d-flex gap-2">
|
||||||
|
<NuxtLink class="text-decoration-none d-inline-block text-light m-0" to="https://blossomishymae.github.io"><h5 class="text-light mb-0">Blossomi Shymae</h5></NuxtLink>
|
||||||
|
<NuxtLink class="text-decoration-none d-inline-block text-light m-0" to="https://github.com/BlossomiShymae"><span><MaterialIcon name="github" :size="20" /> </span></NuxtLink>
|
||||||
|
</div>
|
||||||
|
<h5 class="fw-bold m-0 mb-2">Lonely elf girl</h5>
|
||||||
|
<p>She likes to chat with her friends and do random programming projects, such as this one.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 d-flex flex-column justify-content-around">
|
||||||
|
<div>
|
||||||
|
<h3 class="fw-light">Technology stack</h3>
|
||||||
|
<p>This website uses Nuxt.js, the meta-framework of universal application.</p>
|
||||||
|
<p >Other libraries used include Bootstrap, the CSS framework, and Material Design for icons.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="fw-light">Contact</h3>
|
||||||
|
<p>Blossomi Shymae can be reached via her Discord server.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MaterialIcon from '~/components/MaterialIcon.vue';
|
||||||
|
import TheTitle from '~/components/TheTitle.vue';
|
||||||
|
</script>
|
||||||
57
pages/index.vue
Normal file
57
pages/index.vue
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="d-flex flex-column justify-content-center align-items-center gap-2" style="margin-top: 25%;">
|
||||||
|
<div class="d-flex flex-column justify-content-center align-items-center">
|
||||||
|
<h1 class="display-4"><TheTitle /></h1>
|
||||||
|
<p>Your local League of Legends companion index.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<h2>The <TheTitle /> Project</h2>
|
||||||
|
<p>Our primary purpose is to make game data viewable in a human-friendly
|
||||||
|
format without needing computer programming or scripting knowledge.
|
||||||
|
</p>
|
||||||
|
<p>CommunityDragon, the unofficial League of Legends data resource, is used for our project.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<h2>Resources</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<div class="d-flex flex-column justify-content-center align-items-stretch gap-2">
|
||||||
|
<a class="btn btn-dark bg-transparent bg-blur-3 border-light border-opacity-25" asp-area="" asp-page="/Champion/Index">
|
||||||
|
<MaterialIcon name="account-group" :size="24"/> Champions
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-dark bg-transparent bg-blur-3 border-light border-opacity-25">
|
||||||
|
<MaterialIcon name="magic-staff" :size="24"/> Items
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-dark bg-transparent bg-blur-3 border-light border-opacity-25">
|
||||||
|
<MaterialIcon name="shield" :size="24"/> Runes
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<div class="d-flex flex-column justify-content-center align-items-stretch gap-2">
|
||||||
|
<a class="btn btn-dark bg-transparent bg-blur-3 border-light border-opacity-25">
|
||||||
|
<MaterialIcon name="image" :size="24"/> Summoner Icons
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-dark bg-transparent bg-blur-3 border-light border-opacity-25">
|
||||||
|
<MaterialIcon name="floor-lamp" :size="24"/> Ward Skins
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-dark bg-transparent bg-blur-3 border-light border-opacity-25">
|
||||||
|
<MaterialIcon name="face-woman-shimmer" :size="24"/> Emotes
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import MaterialIcon from '~/components/MaterialIcon.vue';
|
||||||
|
import TheTitle from '~/components/TheTitle.vue';
|
||||||
|
</script>
|
||||||
49
pages/items/index.vue
Normal file
49
pages/items/index.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div class="d-flex flex-column gap-2">
|
||||||
|
<h1>Items</h1>
|
||||||
|
|
||||||
|
<div class="overflow-hidden rounded border border-light border-opacity-25 p-4">
|
||||||
|
<table class="sortable table table-borderless">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Id</th>
|
||||||
|
<th scope="col">Icon</th>
|
||||||
|
<th scope="col">Name</th>
|
||||||
|
<th scope="col">Price</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="item in items" :key="item.id">
|
||||||
|
<th scope="row">
|
||||||
|
<NuxtLink class="text-decoration-none text-light" :to="`/items/overview/${item.id}`">
|
||||||
|
{{ item.id }}
|
||||||
|
</NuxtLink>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<NuxtLink class="text-decoration-none text-light" :to="`/items/overview/${item.id}`">
|
||||||
|
<img class="rounded" :src="item.getIcon('latest')" width="32" height="32" loading="lazy" onerror="this.onerror = null; this.src = '/img/error.png'"/>
|
||||||
|
</NuxtLink>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<NuxtLink class="text-decoration-none text-light" :to="`/items/overview/${item.id}`">
|
||||||
|
<span v-html="item.name"></span>
|
||||||
|
</NuxtLink>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<NuxtLink class="text-decoration-none text-light" :to="`/items/overview/${item.id}`">
|
||||||
|
{{ item.priceTotal }}
|
||||||
|
</NuxtLink>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import useClient from '../../composables/useClient';
|
||||||
|
|
||||||
|
const { client } = useClient();
|
||||||
|
const items = await client.items.listAsync({ locale: "default", version: "latest"});
|
||||||
|
</script>
|
||||||
68
pages/items/overview/[id].vue
Normal file
68
pages/items/overview/[id].vue
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<h1 class="display-4 mb-0"> {{ item.name }}</h1>
|
||||||
|
<p class="text-muted" v-html="item.description"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 col-sm-12 d-flex justify-content-center align-items-center">
|
||||||
|
<img class="border rounded border-dark" :src="item.getIcon('latest')"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="d-flex flex-wrap gap-3">
|
||||||
|
<Badge name="identifier">{{ item.id }}</Badge>
|
||||||
|
<Badge name="hand-coin">{{ item.priceTotal }}</Badge>
|
||||||
|
<Badge name="hand-coin-outline">{{ item.price }}</Badge>
|
||||||
|
<Badge name="keyboard-variant" v-if="item.active">Active</Badge>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-4">
|
||||||
|
<div class="col-md-6 col-sm-12 border-start border-light border-opacity-25 border-4"
|
||||||
|
v-if="components.length > 0">
|
||||||
|
<h4 class="fw-light">Component</h4>
|
||||||
|
<div class="d-flex justify-content-around align-items-center gap-2 flex-wrap">
|
||||||
|
<NuxtLink v-for="component in components" :to="`/items/overview/${component.id}`" :key="component.id">
|
||||||
|
<img class="border rounded border-dark" :src="component.getIcon('latest')"/>
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 col-sm-12 border-start border-light border-opacity-25 border-4"
|
||||||
|
v-if="composites.length > 0">
|
||||||
|
<h4 class="fw-light">Composite</h4>
|
||||||
|
<div class="d-flex justify-content-around align-items-center gap-2 flex-wrap">
|
||||||
|
<NuxtLink v-for="composite in composites" :to="`/items/overview/${composite.id}`" :key="composite.id">
|
||||||
|
<img class="border rounded border-dark" :src="composite.getIcon('latest')"/>
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import useClient from '../../../composables/useClient';
|
||||||
|
import { Item } from '~/core/models';
|
||||||
|
import Badge from '~/components/Badge.vue';
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const id = route.params.id as unknown;
|
||||||
|
|
||||||
|
const { client } = useClient();
|
||||||
|
const items = await client.items.listAsync({locale: "default", version: "latest"});
|
||||||
|
const _default = new Item({});
|
||||||
|
|
||||||
|
const item = items.find((x) => x.id == id) || _default;
|
||||||
|
const components = item.from.map((id) => items.find((x) => x.id == id) || _default);
|
||||||
|
const composites = item.to.map((id) => items.find((x) => x.id == id) || _default);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
BIN
preview.png
Normal file
BIN
preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 744 KiB |
0
public/.nojekyll
Normal file
0
public/.nojekyll
Normal file
133
public/css/app.css
Normal file
133
public/css/app.css
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
* {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-position: center;
|
||||||
|
min-height: 100%;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: #0008;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
backdrop-filter: blur(0.2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
background-color: transparent;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
html {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:focus,
|
||||||
|
.btn:active:focus,
|
||||||
|
.btn-link.nav-link:focus,
|
||||||
|
.form-control:focus,
|
||||||
|
.form-check-input:focus,
|
||||||
|
a:focus-visible {
|
||||||
|
box-shadow: 0.05rem 0.05rem 0.375rem 0.1rem rgba(255, 255, 255, 0.744) !important;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
top: 0;
|
||||||
|
position: sticky;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: #0004;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
filter: invert(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
background-color: #0004 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead, tbody, th, td {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table > tbody > tr:nth-of-type(2n+1) > * {
|
||||||
|
background-color: #0004 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table > tbody > tr:hover > * {
|
||||||
|
background-color: #0008 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-screen {
|
||||||
|
background-color: #0008;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-screen {
|
||||||
|
background-color: #0004 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-transparent {
|
||||||
|
background-color: transparent;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-blur {
|
||||||
|
backdrop-filter: blur(0.2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blur {
|
||||||
|
backdrop-filter: blur(0.2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-blur-2 {
|
||||||
|
backdrop-filter: blur(0.4rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blur-2 {
|
||||||
|
backdrop-filter: blur(0.4rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blur-3 {
|
||||||
|
backdrop-filter: blur(0.6rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blur-4 {
|
||||||
|
backdrop-filter: blur(0.8rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-index--10 {
|
||||||
|
z-index: -10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-index-10 {
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
BIN
public/img/avatar.png
Normal file
BIN
public/img/avatar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 344 KiB |
BIN
public/img/error.png
Normal file
BIN
public/img/error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
1
public/lib/MaterialDesign
Submodule
1
public/lib/MaterialDesign
Submodule
Submodule public/lib/MaterialDesign added at 49bf943a7a
3
server/tsconfig.json
Normal file
3
server/tsconfig.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "../.nuxt/tsconfig.server.json"
|
||||||
|
}
|
||||||
4
tsconfig.json
Normal file
4
tsconfig.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
// https://nuxt.com/docs/guide/concepts/typescript
|
||||||
|
"extends": "./.nuxt/tsconfig.json"
|
||||||
|
}
|
||||||
50
utils/paginated-array.ts
Normal file
50
utils/paginated-array.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
export class PaginatedArray<T> extends Array<T> {
|
||||||
|
pageSize: number;
|
||||||
|
items: Array<T>;
|
||||||
|
pageIndex: number;
|
||||||
|
totalPages: number;
|
||||||
|
|
||||||
|
constructor(items: Array<T>, pageIndex: number, pageSize: number) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
this.items = items;
|
||||||
|
|
||||||
|
this.pageIndex = pageIndex;
|
||||||
|
this.totalPages = Math.ceil(items.length / pageSize);
|
||||||
|
|
||||||
|
this.push(...items.slice((pageIndex - 1) * pageSize).slice(0, pageSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
public get hasFurtherPreviousPage() {
|
||||||
|
return this.pageIndex > 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get hasPreviousPage() {
|
||||||
|
return this.pageIndex > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get hasNextPage() {
|
||||||
|
return this.pageIndex < this.totalPages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get hasFurtherNextPage() {
|
||||||
|
return this.pageIndex < this.totalPages - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get furtherPreviousPage() {
|
||||||
|
return this.pageIndex - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get previousPage() {
|
||||||
|
return this.pageIndex - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get nextPage() {
|
||||||
|
return this.pageIndex + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get furtherNextPage() {
|
||||||
|
return this.pageIndex + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user