diff --git a/web/app/Helpers/AssetHelper.php b/web/app/Helpers/AssetHelper.php index 97fcaf6..faac6b8 100644 --- a/web/app/Helpers/AssetHelper.php +++ b/web/app/Helpers/AssetHelper.php @@ -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' ]; } diff --git a/web/database/migrations/2022_06_05_140351_create_assets_table.php b/web/database/migrations/2022_06_05_140351_create_assets_table.php index 734cf29..c02d27a 100644 --- a/web/database/migrations/2022_06_05_140351_create_assets_table.php +++ b/web/database/migrations/2022_06_05_140351_create_assets_table.php @@ -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. diff --git a/web/package-lock.json b/web/package-lock.json index b20824a..c594000 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -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", diff --git a/web/package.json b/web/package.json index e1d702d..ffabef5 100644 --- a/web/package.json +++ b/web/package.json @@ -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", diff --git a/web/resources/js/components/Shop.js b/web/resources/js/components/Shop.js index edb14a2..aa46ea1 100644 --- a/web/resources/js/components/Shop.js +++ b/web/resources/js/components/Shop.js @@ -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 ( + + { this.props.label } + + ); + } +} + +class ShopCategories extends Component { + constructor(props) { + super(props); + } + + render() { + return ( +
+
Category
+ + +
+ ); + } +} 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 {
-
-
Category
- All Items - -
+
-
- -
+ { + this.state.pageLoading ? +
+ +
+ : + null + }
@@ -113,15 +281,15 @@ class Shop extends Component {
  • - +
  • Page  - +  of 20
  • - +