Some more shop stuff.

This commit is contained in:
Graphictoria 2022-07-05 23:45:02 -04:00
parent 0321c8ecf6
commit ebc725296a
5 changed files with 144 additions and 31 deletions

View File

@ -0,0 +1,25 @@
<?php
/*
Graphictoria 2022
Validation Helper
*/
namespace App\Helpers;
use Illuminate\Validation\Validator;
class ValidationHelper
{
public static function generateErrorJSON(Validator $validator) {
$errorModel = [
'errors' => []
];
foreach($validator->errors()->all() as $error) {
array_push($errorModel['errors'], ['code' => 400, 'message' => $error]);
}
return $errorModel;
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers\Api;
use App\Helpers\ValidationHelper;
use App\Http\Controllers\Controller;
use App\Models\Asset;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class ShopController extends Controller
{
protected static function generateValidatorError($validator) {
return response(ValidationHelper::generateErrorJSON($validator), 400);
}
protected function listjson(Request $request)
{
$validator = Validator::make($request->all(), [
'assetTypeId' => ['required', 'regex:/^\\d(,?\\d)*$/i'],
'gearGenreId' => ['regex:/^\\d(,?\\d)*$/i']
]);
if($validator->fails()) {
return ShopController::generateValidatorError($validator);
}
$valid = $validator->valid();
if($valid['assetTypeId'] != '19' && isset($valid['gearGenreId'])) {
$validator->errors()->add('gearGenreId', 'gearGenreId can only be used with typeId 19.');
return ShopController::generateValidatorError($validator);
}
return response([
'data' => [],
'next_cursor' => null,
'prev_cursor' => null
]);
}
}

View File

@ -199,7 +199,9 @@ class Shop extends Component {
super(props); super(props);
this.state = { this.state = {
selectedCategoryId: -1, selectedCategoryId: -1,
pageLoading: true pageItems: [],
pageLoaded: true,
error: false
}; };
this.navigateCategory = this.navigateCategory.bind(this); this.navigateCategory = this.navigateCategory.bind(this);
@ -233,9 +235,34 @@ class Shop extends Component {
} }
navigateCategory(categoryId, data) { navigateCategory(categoryId, data) {
this.setState({selectedCategoryId: categoryId}); this.setState({selectedCategoryId: categoryId, pageLoaded: false});
console.log(data); let url = buildGenericApiUrl('api', 'catalog/v1/list-json');
let paramIterator = 0;
Object.keys(data).filter(key => {
if (key == 'label')
return false;
return true;
}).map(key => {
url += ((paramIterator++ == 0 ? '?' : '&') + `${key}=${data[key]}`);
});
axios.get(url)
.then(res => {
const items = res.data;
this.nextCursor = items.next_cursor;
this.setState({ pageItems: items.data, pageLoaded: true, error: false });
}).catch(err => {
const data = err.response;
let errorMessage = 'An error occurred while processing your request.';
if(data.errors)
errorMessage = data.errors[0].message;
this.setState({ pageItems: [], pageLoaded: true, error: errorMessage });
this.inputBox.current.focus();
});
} }
render() { render() {
@ -260,36 +287,51 @@ class Shop extends Component {
<div className="col-md-10 d-flex flex-column"> <div className="col-md-10 d-flex flex-column">
<div className="card p-3"> <div className="card p-3">
{ {
this.state.pageLoading ? this.state.error ?
<div className="alert alert-danger p-2 mb-0 text-center">{this.state.error}</div>
:
null
}
{
!this.state.pageLoaded ?
<div className="graphictoria-shop-overlay"> <div className="graphictoria-shop-overlay">
<Loader /> <Loader />
</div> </div>
: :
null null
} }
<div> {
<a className="graphictoria-item-card" href="#"> (this.state.pageItems.length == 0 && !this.state.error) ?
<span className="card m-2"> <p className="text-muted text-center">Nothing found.</p>
<img className="img-fluid" src="https://gtoria.local/images/testing/hat.png" /> :
<div className="p-2"> <div>
<p>Test hat</p> {
<p className="text-muted">Free</p> this.state.pageItems.map(({}, index) => {
</div> <a className="graphictoria-item-card" href="#" key={index}>
</span> <span className="card m-2">
</a> <img className="img-fluid" src="https://gtoria.local/images/testing/hat.png" />
</div> <div className="p-2">
<p>Test hat</p>
<p className="text-muted">Free</p>
</div>
</span>
</a>
})
}
</div>
}
</div> </div>
<ul className="list-inline mx-auto mt-3"> <ul className="list-inline mx-auto mt-3">
<li className="list-inline-item"> <li className="list-inline-item">
<button className="btn btn-secondary" disabled={this.state.pageLoading ? "" : null}><i className="fa-solid fa-angle-left"></i></button> <button className="btn btn-secondary" disabled={this.state.pageLoaded ? null : true}><i className="fa-solid fa-angle-left"></i></button>
</li> </li>
<li className="list-inline-item graphictoria-paginator"> <li className="list-inline-item graphictoria-paginator">
<span>Page&nbsp;</span> <span>Page&nbsp;</span>
<input type="text" value="1" className="form-control" disabled={this.state.pageLoading ? "" : null} /> <input type="text" value="1" className="form-control" disabled={this.state.pageLoaded ? null : true} />
<span>&nbsp;of 20</span> <span>&nbsp;of 20</span>
</li> </li>
<li className="list-inline-item"> <li className="list-inline-item">
<button className="btn btn-secondary" disabled={this.state.pageLoading ? "" : null}><i className="fa-solid fa-angle-right"></i></button> <button className="btn btn-secondary" disabled={this.state.pageLoaded ? null : true}><i className="fa-solid fa-angle-right"></i></button>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -52,21 +52,20 @@ img.twemoji {
padding: 0; padding: 0;
flex: 0 0 auto; flex: 0 0 auto;
width: math.div(100%, 3);
@media (max-width: 576px) {
flex: 0 0 auto;
width: math.div(100%, 2);
}
@media (min-width: 576px) {
flex: 0 0 auto;
width: math.div(100%, 4);
}
@media (min-width: 768px) { @media (min-width: 768px) {
flex: 0 0 auto; flex: 0 0 auto;
width: math.div(100%, 5); width: 144px;
}
@media (min-width: 992px) {
flex: 0 0 auto;
width: math.div(100%, 7);
}
@media (min-width: 1400px) {
flex: 0 0 auto;
width: math.div(100%, 8);
} }
} }

View File

@ -6,11 +6,17 @@ Route::middleware('auth')->group(function () {
Route::group(['as' => 'feed.', 'prefix' => 'feed'], function() { Route::group(['as' => 'feed.', 'prefix' => 'feed'], function() {
Route::group(['as' => 'v1.', 'prefix' => 'v1'], function() { Route::group(['as' => 'v1.', 'prefix' => 'v1'], function() {
Route::get('/list-json', 'FeedController@listjson')->name('list'); Route::get('/list-json', 'FeedController@listjson')->name('list');
Route::post('/share ', 'FeedController@share')->name('share')->middleware('throttle:3,2'); Route::post('/share', 'FeedController@share')->name('share')->middleware('throttle:3,2');
}); });
}); });
}); });
Route::group(['as' => 'catalog.', 'prefix' => 'catalog'], function() {
Route::group(['as' => 'v1.', 'prefix' => 'v1'], function() {
Route::get('/list-json', 'ShopController@listjson')->name('list');
});
});
Route::fallback(function () { Route::fallback(function () {
return response('404 not found.', 404) return response('404 not found.', 404)
->header('Content-Type', 'text/plain'); ->header('Content-Type', 'text/plain');