Catalog categories nearly functional, just need to set up APIs. Also added gear attributes/genres, and normal asset genres.

This commit is contained in:
Graphictoria 2022-06-22 00:51:04 -04:00
parent c0461f57c0
commit 0321c8ecf6
5 changed files with 275 additions and 59 deletions

View File

@ -10,6 +10,7 @@ namespace App\Helpers;
class AssetHelper
{
public static $assetTypes = [
[0] = 'Product',
[1] = 'Image',
[2] = 'T-Shirt',
[3] = 'Audio',
@ -81,6 +82,40 @@ class AssetHelper
[69] = 'Shorts Accessory',
[70] = 'Left Shoe Accessory',
[71] = 'Right Shoe Accessory',
[72] = 'Dress Skirt Accessory'
[72] = 'Dress Skirt Accessory',
[73] = 'Font Family',
[74] = 'Font Face',
[75] = 'MeshHiddenSurfaceRemoval'
];
public static $assetGenres = [
[0] = 'All',
[1] = 'Town And City',
[2] = 'Medieval',
[3] = 'Sci-Fi',
[4] = 'Fighting',
[5] = 'Horror',
[6] = 'Naval',
[7] = 'Adventure',
[8] = 'Sports',
[9] = 'Comedy',
[10] = 'Western',
[11] = 'Military',
[12] = 'Skate Park',
[13] = 'Building',
[14] = 'FPS',
[15] = 'RPG'
];
public static $gearAssetGenres = [
[0] = 'Melee Weapon',
[1] = 'Ranged Weapon',
[2] = 'Explosive',
[3] = 'Power Up',
[4] = 'Navigation Enhancer',
[5] = 'Musical Instrument',
[6] = 'Social Item',
[7] = 'Building Tool',
[8] = 'Personal Transport'
];
}

View File

@ -28,6 +28,7 @@ return new class extends Migration
$table->boolean('onSale')->default(false);
$table->unsignedSmallInteger('assetTypeId');
$table->unsignedSmallInteger('assetAttributeId')->nullable();
$table->unsignedBigInteger('assetVersionId')->comment('The most recent version id for the asset. This is used internally as asset version 0 when using the /asset api.');
// Calculating the subdomain on runtime is too expensive.

11
web/package-lock.json generated
View File

@ -5,6 +5,7 @@
"packages": {
"": {
"dependencies": {
"classnames": "^2.3.1",
"install": "^0.13.0",
"laravel-mix-banner": "^0.1.4",
"npm": "^8.9.0",
@ -3222,6 +3223,11 @@
"safe-buffer": "^5.0.1"
}
},
"node_modules/classnames": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
},
"node_modules/clean-css": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz",
@ -14218,6 +14224,11 @@
"safe-buffer": "^5.0.1"
}
},
"classnames": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
},
"clean-css": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz",

View File

@ -30,6 +30,7 @@
"tailwindcss": "^3.0.24"
},
"dependencies": {
"classnames": "^2.3.1",
"install": "^0.13.0",
"laravel-mix-banner": "^0.1.4",
"npm": "^8.9.0",

View File

@ -3,6 +3,8 @@
import { Component, createRef } from 'react';
import classNames from 'classnames/bind';
import axios from 'axios';
import Twemoji from 'react-twemoji';
@ -12,21 +14,228 @@ import Loader from './Loader';
axios.defaults.withCredentials = true;
const shopCategories = [
['Clothing'] = [
const shopCategories = {
'Clothing': [
{
label: 'Hats',
assetTypeId: 0
assetTypeId: 8
},
{
label: 'Shirts',
assetTypeId: 11
},
{
label: 'T-Shirts',
assetTypeId: 2
},
{
label: 'Pants',
assetTypeId: 12
},
{
label: 'Package',
assetTypeId: 32
}
],
'Body Parts': [
{
label: 'Heads',
assetTypeId: 17
},
{
label: 'Faces',
assetTypeId: 18
},
{
label: 'Packages',
assetTypeId: 32
}
],
'Gear': [
{
label: 'Building',
assetTypeId: 19,
gearGenreId: 7
},
{
label: 'Explosive',
assetTypeId: 19,
gearGenreId: 2
},
{
label: 'Melee',
assetTypeId: 19,
gearGenreId: 0
},
{
label: 'Musical',
assetTypeId: 19,
gearGenreId: 5
},
{
label: 'Navigation',
assetTypeId: 19,
gearGenreId: 4
},
{
label: 'Power Up',
assetTypeId: 19,
gearGenreId: 3
},
{
label: 'Ranged',
assetTypeId: 19,
gearGenreId: 1
},
{
label: 'Social',
assetTypeId: 19,
gearGenreId: 6
},
{
label: 'Transport',
assetTypeId: 19,
gearGenreId: 8
}
]
];
};
function makeCategoryId(originalName, category) {
return `shop-${originalName.toLowerCase().replaceAll(' ', '-')}-${category}`;
}
class ShopCategoryButton extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
if (this.props.id === 'all') {
let assetTypes = [];
Object.keys(shopCategories).map((categoryName) => {
let categoryAssetTypeIds = this.props.getCategoryAssetTypeIds(categoryName);
switch(typeof(categoryAssetTypeIds.assetTypeId)) {
case 'number':
assetTypes[categoryAssetTypeIds.assetTypeId] = true;
break;
case 'object':
categoryAssetTypeIds.assetTypeId.map((assetTypeId) => {
assetTypes[assetTypeId] = true;
});
break;
}
});
this.data = {assetTypeId: Object.keys(assetTypes)};
} else if (this.props.id.startsWith('shop-all')) {
this.data = this.props.getCategoryAssetTypeIds(this.props.categoryName);
} else {
this.data = this.props.getCategoryAssetTypeByLabel(this.props.categoryName, this.props.label);
}
if (this.props.id == 'shop-hats-clothing-type')
this.props.navigateCategory(this.props.id, this.data);
}
handleClick() {
this.props.navigateCategory(this.props.id, this.data);
}
render() {
return (
<a href="#"
className={classNames({
'text-decoration-none': true,
'ms-2': (this.props.id != 'all'),
'fw-bold': (this.props.shopState.selectedCategoryId == this.props.id)
})}
onClick={this.handleClick}>
{ this.props.label }
</a>
);
}
}
class ShopCategories extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="graphictoria-shop-categories">
<h5>Category</h5>
<ShopCategoryButton id="all" label="All Items" getCategoryAssetTypeByLabel={this.props.getCategoryAssetTypeByLabel} getCategoryAssetTypeIds={this.props.getCategoryAssetTypeIds} navigateCategory={this.props.navigateCategory} shopState={this.props.shopState} />
<ul className="list-unstyled ps-0">
{
Object.keys(shopCategories).map((categoryName, index) =>
<li className="mb-1">
<a className="text-decoration-none fw-normal align-items-center graphictoria-list-dropdown" data-bs-toggle="collapse" data-bs-target={`#${makeCategoryId(categoryName, 'collapse')}`} aria-expanded={(index === 0 ? 'true' : 'false')} href="#">{ categoryName }</a>
<div className={classNames({'collapse': true, 'show': (index === 0)})} id={makeCategoryId(categoryName, 'collapse')}>
<ul className="btn-toggle-nav list-unstyled fw-normal small">
<li><ShopCategoryButton id={makeCategoryId(`all-${categoryName}`, 'type')} label={`All ${categoryName}`} categoryName={categoryName} getCategoryAssetTypeByLabel={this.props.getCategoryAssetTypeByLabel} getCategoryAssetTypeIds={this.props.getCategoryAssetTypeIds} navigateCategory={this.props.navigateCategory} shopState={this.props.shopState} /></li>
{
shopCategories[categoryName].map(({label, assetTypeId, gearGenreId}, index) =>
<li><ShopCategoryButton id={makeCategoryId(`${label}-${categoryName}`, 'type')} label={label} categoryName={categoryName} getCategoryAssetTypeByLabel={this.props.getCategoryAssetTypeByLabel} getCategoryAssetTypeIds={this.props.getCategoryAssetTypeIds} navigateCategory={this.props.navigateCategory} shopState={this.props.shopState} /></li>
)
}
</ul>
</div>
</li>
)
}
</ul>
</div>
);
}
}
class Shop extends Component {
constructor(props) {
super(props);
this.state = {
selectedCategoryId: -1,
pageLoading: true
};
this.navigateCategory = this.navigateCategory.bind(this);
}
getCategoryAssetTypeIds(categoryName) {
let assetTypes = [];
shopCategories[categoryName].map(({assetTypeId}) => {
assetTypes[assetTypeId] = true;
});
assetTypes = Object.keys(assetTypes);
if (assetTypes.length == 1)
assetTypes = assetTypes[0];
return {assetTypeId: assetTypes};
}
getCategoryAssetTypeByLabel(categoryName, label) {
let assetType = -1;
shopCategories[categoryName].map((sort) => {
if (sort.label === label) {
assetType = sort;
}
});
return assetType;
}
navigateCategory(categoryId, data) {
this.setState({selectedCategoryId: categoryId});
console.log(data);
}
render() {
@ -46,59 +255,18 @@ class Shop extends Component {
</div>
<div className="row">
<div className="col-md-2">
<div className="graphictoria-shop-categories">
<h5>Category</h5>
<a href="#" className="text-decoration-none">All Items</a>
<ul className="list-unstyled ps-0">
<li className="mb-1">
<a className="text-decoration-none fw-normal align-items-center graphictoria-list-dropdown" data-bs-toggle="collapse" data-bs-target="#shop-clothing-collapse" aria-expanded="true" href="#">Clothing</a>
<div className="collapse show" id="shop-clothing-collapse">
<ul className="btn-toggle-nav list-unstyled fw-normal small">
<li><a href="#" className="text-decoration-none ms-2">All Clothing</a></li>
<li><a href="#" className="fw-bold text-decoration-none ms-2">Hats</a></li>
<li><a href="#" className="text-decoration-none ms-2">Shirts</a></li>
<li><a href="#" className="text-decoration-none ms-2">T-Shirts</a></li>
<li><a href="#" className="text-decoration-none ms-2">Pants</a></li>
<li><a href="#" className="text-decoration-none ms-2">Packages</a></li>
</ul>
</div>
</li>
<li className="mb-1">
<a className="text-decoration-none fw-normal align-items-center graphictoria-list-dropdown" data-bs-toggle="collapse" data-bs-target="#shop-bodyparts-collapse" aria-expanded="false" href="#">Body Parts</a>
<div className="collapse" id="shop-bodyparts-collapse">
<ul className="btn-toggle-nav list-unstyled fw-normal small">
<li><a href="#" className="text-decoration-none ms-2">All Body Parts</a></li>
<li><a href="#" className="text-decoration-none ms-2">Heads</a></li>
<li><a href="#" className="text-decoration-none ms-2">Faces</a></li>
<li><a href="#" className="text-decoration-none ms-2">Packages</a></li>
</ul>
</div>
</li>
<li className="mb-1">
<a className="text-decoration-none fw-normal align-items-center graphictoria-list-dropdown" data-bs-toggle="collapse" data-bs-target="#shop-gear-collapse" aria-expanded="false" href="#">Gear</a>
<div className="collapse" id="shop-gear-collapse">
<ul className="btn-toggle-nav list-unstyled fw-normal small">
<li><a href="#" className="text-decoration-none ms-2">All Gear</a></li>
<li><a href="#" className="text-decoration-none ms-2">Building</a></li>
<li><a href="#" className="text-decoration-none ms-2">Explosive</a></li>
<li><a href="#" className="text-decoration-none ms-2">Melee</a></li>
<li><a href="#" className="text-decoration-none ms-2">Musical</a></li>
<li><a href="#" className="text-decoration-none ms-2">Navigation</a></li>
<li><a href="#" className="text-decoration-none ms-2">Power Up</a></li>
<li><a href="#" className="text-decoration-none ms-2">Ranged</a></li>
<li><a href="#" className="text-decoration-none ms-2">Social</a></li>
<li><a href="#" className="text-decoration-none ms-2">Transport</a></li>
</ul>
</div>
</li>
</ul>
</div>
<ShopCategories getCategoryAssetTypeByLabel={this.getCategoryAssetTypeByLabel} getCategoryAssetTypeIds={this.getCategoryAssetTypeIds} navigateCategory={this.navigateCategory} shopState={this.state} />
</div>
<div className="col-md-10 d-flex flex-column">
<div className="card p-3">
<div className="graphictoria-shop-overlay">
<Loader />
</div>
{
this.state.pageLoading ?
<div className="graphictoria-shop-overlay">
<Loader />
</div>
:
null
}
<div>
<a className="graphictoria-item-card" href="#">
<span className="card m-2">
@ -113,15 +281,15 @@ class Shop extends Component {
</div>
<ul className="list-inline mx-auto mt-3">
<li className="list-inline-item">
<button className="btn btn-secondary" disabled><i className="fa-solid fa-angle-left"></i></button>
<button className="btn btn-secondary" disabled={this.state.pageLoading ? "" : null}><i className="fa-solid fa-angle-left"></i></button>
</li>
<li className="list-inline-item graphictoria-paginator">
<span>Page&nbsp;</span>
<input type="text" value="1" className="form-control" disabled />
<input type="text" value="1" className="form-control" disabled={this.state.pageLoading ? "" : null} />
<span>&nbsp;of 20</span>
</li>
<li className="list-inline-item">
<button className="btn btn-secondary" disabled><i className="fa-solid fa-angle-right"></i></button>
<button className="btn btn-secondary" disabled={this.state.pageLoading ? "" : null}><i className="fa-solid fa-angle-right"></i></button>
</li>
</ul>
</div>