parent
6ec79d2f36
commit
97d08c62d5
|
|
@ -12,6 +12,9 @@ use App\Models\Category;
|
|||
use App\Models\Post;
|
||||
use App\Models\Reply;
|
||||
use App\Models\Staff;
|
||||
use App\Models\CatalogCategory;
|
||||
use App\Models\Item;
|
||||
use App\Models\Inventory;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
|
@ -41,6 +44,8 @@ class Controller extends BaseController
|
|||
$array = $user->toArray();
|
||||
$staff = Staff::where('user_id', $user->id)->first();
|
||||
if ($staff) {$array['power'] = $staff->power_level;}
|
||||
$array['bank'] = $user->bank;
|
||||
$array['email'] = $user->email;
|
||||
return Response()->json(["data"=>$array]);
|
||||
break;
|
||||
case "fetchedUser":
|
||||
|
|
@ -86,6 +91,29 @@ class Controller extends BaseController
|
|||
|
||||
}
|
||||
|
||||
public function fetchCategoriesCatalog() {
|
||||
|
||||
$categories = CatalogCategory::get();
|
||||
|
||||
return Response()->json(["categories"=>$categories]);
|
||||
|
||||
}
|
||||
|
||||
public function fetchCategoryCatalog($id) {
|
||||
|
||||
$category = CatalogCategory::where('id', $id)->first();
|
||||
|
||||
if (!$category) {return Response()->json(false);}
|
||||
|
||||
$items = $category->items()->orderBy('updated_at', 'desc')->paginate(25);
|
||||
|
||||
foreach ($items as &$item) {
|
||||
$item['creator'] = User::where('id', $item['creator_id'])->first();
|
||||
}
|
||||
|
||||
return Response()->json(["data"=>$category, "items"=>$items]);
|
||||
}
|
||||
|
||||
public function fetchCategory($id) {
|
||||
|
||||
$category = Category::where('id', $id)->first();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class CatalogCategory extends Model
|
||||
{
|
||||
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'catalog_categories';
|
||||
|
||||
function items()
|
||||
{
|
||||
return $this->morphMany('App\Models\Item', 'category');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Inventory extends Model
|
||||
{
|
||||
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'inventories';
|
||||
|
||||
public function item() {
|
||||
return $this->belongsTo(Item::class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Item extends Model
|
||||
{
|
||||
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'items';
|
||||
|
||||
}
|
||||
|
|
@ -33,7 +33,9 @@ class User extends Authenticatable
|
|||
'password',
|
||||
'remember_token',
|
||||
'token',
|
||||
'email'
|
||||
'email',
|
||||
'email_verified_at',
|
||||
'bank'
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -49,5 +51,9 @@ class User extends Authenticatable
|
|||
$staff = Staff::where('user_id', $this->id)->first();
|
||||
return $staff;
|
||||
}
|
||||
|
||||
public function inventory() {
|
||||
return $this->morphMany('App\Models\Inventory', 'owner');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class CreateUsersTable extends Migration
|
|||
$table->timestamp('email_verified_at')->default(null);
|
||||
$table->string('password');
|
||||
$table->string('token');
|
||||
$table->integer('bank')->default(150);
|
||||
$table->string('about')->default(null);
|
||||
$table->timestamps();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateItemsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title');
|
||||
$table->string('description');
|
||||
$table->string('thumbnail');
|
||||
$table->integer('creator_id');
|
||||
$table->integer('starting_price')->default(5);
|
||||
$table->integer('current_price')->default(5);
|
||||
$table->integer('category_id')->default(1);
|
||||
$table->string('category_type');
|
||||
//may need to add more later idk.
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('items');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateInventoriesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('inventories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('item_id');
|
||||
$table->string('owner_id');
|
||||
$table->string('owner_type');
|
||||
$table->string('uid'); //unique id | used for limiteds, the original id of the inventory row. once set, it never changes
|
||||
$table->boolean('status')->default(true);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('inventories');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateCatalogCategoriesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('catalog_categories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title');
|
||||
$table->string('description');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('catalog_categories');
|
||||
}
|
||||
}
|
||||
|
|
@ -51,13 +51,16 @@ const Navbar = (props) => {
|
|||
<>
|
||||
<SearchBar />
|
||||
{props.user?
|
||||
<li className="nav-item dropdown">
|
||||
<button className="btn btn-secondary nav-link dropdown-toggle" href="#" id="graphictoria-nav-dropdown" role="button" data-bs-toggle="dropdown" area-expanded="false">{props.user.username}</button>
|
||||
<ul className="dropdown-menu graphictoria-nav-dropdown" area-labelledby="graphictoria-nav-dropdown">
|
||||
<li><NavLink className="dropdown-item" to="/auth/settings">Settings</NavLink></li>
|
||||
<li><a className="dropdown-item" href={`/account/logout`}>Logout</a></li>
|
||||
</ul>
|
||||
</li> : <Link className="btn btn-success" to="/login">Login / Sign up</Link>}
|
||||
<div className={`flex row`}>
|
||||
<div className={`flex row col flex alc`}>Bank: ${props.user.bank}</div>
|
||||
<li className="nav-item dropdown col flex alc">
|
||||
<button className="btn btn-secondary nav-link dropdown-toggle" href="#" id="graphictoria-nav-dropdown" role="button" data-bs-toggle="dropdown" area-expanded="false">{props.user.username}</button>
|
||||
<ul className="dropdown-menu graphictoria-nav-dropdown" area-labelledby="graphictoria-nav-dropdown">
|
||||
<li><NavLink className="dropdown-item" to="/auth/settings">Settings</NavLink></li>
|
||||
<li><a className="dropdown-item" href={`/account/logout`}>Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div> : <Link className="btn btn-success" to="/login">Login / Sign up</Link>}
|
||||
</>
|
||||
:
|
||||
null
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import CreatePost from '../pages/CreatePost.js';
|
|||
import CreateReply from '../pages/CreateReply.js';
|
||||
import Settings from '../pages/Settings.js';
|
||||
import User from '../pages/User.js';
|
||||
import Catalog from '../pages/Catalog.js';
|
||||
|
||||
axios.defaults.withCredentials = true
|
||||
|
||||
|
|
@ -155,6 +156,14 @@ const App = () => {
|
|||
<Forum user={user}/>
|
||||
</Route>
|
||||
|
||||
<Route exact path="/catalog">
|
||||
<Catalog user={user}/>
|
||||
</Route>
|
||||
|
||||
<Route exact path="/catalog/category/:id">
|
||||
<Catalog user={user}/>
|
||||
</Route>
|
||||
|
||||
<GuardedRoute exact path="/forum/post" meta={{auth: true}}>
|
||||
<CreatePost user={user}/>
|
||||
</GuardedRoute>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
// © XlXi 2021
|
||||
// Graphictoria 5
|
||||
|
||||
import axios from 'axios';
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Link, useHistory, useParams } from "react-router-dom";
|
||||
|
||||
import Config from '../config.js';
|
||||
|
||||
import SetTitle from "../Helpers/Title.js";
|
||||
|
||||
import Loader from '../Components/Loader.js';
|
||||
|
||||
import { GenericErrorModal } from './Errors.js';
|
||||
import { Card, CardTitle } from '../Layouts/Card.js';
|
||||
import { paginate } from '../helpers/utils.js';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
var url = Config.BaseUrl.replace('http://', '');
|
||||
var protocol = Config.Protocol;
|
||||
|
||||
const Catalog = (props) => {
|
||||
|
||||
var id = useParams().id;
|
||||
const [state, setState] = useState({offline: false, loading: true});
|
||||
const [categories, setCategoires] = useState([]);
|
||||
const [category, setCategory] = useState([]);
|
||||
const [items, setItems] = useState({items: [], currentPage: 1, meta: []});
|
||||
const user = props.user;
|
||||
|
||||
if (!id) id = 1;
|
||||
|
||||
const fetchCategories = async () => {
|
||||
await axios.get(`${protocol}apis.${url}/fetch/categories/catalog`, {headers: {"X-Requested-With":"XMLHttpRequest"}}).then(data=>{
|
||||
setCategoires(data.data.categories);
|
||||
}).catch(error=>{console.log(error);});
|
||||
}
|
||||
|
||||
const fetchCategory = async () => {
|
||||
await axios.get(`${protocol}apis.${url}/fetch/category/catalog/${id}?page=${items.currentPage}`, {headers: {"X-Requested-With":"XMLHttpRequest"}}).then(data=>{
|
||||
if (!data.data) {window.location.href=`/forum`;return;}
|
||||
setCategory(data.data.data);
|
||||
setItems({...items, items: data.data.items.data, meta: data.data.items});
|
||||
}).catch(error=>{console.log(error);});
|
||||
}
|
||||
|
||||
const paginateitems = async (decision) => {
|
||||
paginate(decision, items.currentPage, items.meta).then(res=>{
|
||||
switch(res){
|
||||
case "increase":
|
||||
setItems({...items, currentPage: items.currentPage+1});
|
||||
break;
|
||||
case "decrease":
|
||||
setItems({...items, currentPage: items.currentPage-1});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}).catch(error=>console.log(error));
|
||||
}
|
||||
|
||||
useEffect(async ()=>{
|
||||
SetTitle(`Catalog`);
|
||||
await fetchCategory();
|
||||
await fetchCategories();
|
||||
setState({...state, loading: false});
|
||||
}, []);
|
||||
|
||||
useEffect(async()=>{
|
||||
setState({...state, loading: true});
|
||||
await fetchCategory();
|
||||
setState({...state, loading: false});
|
||||
}, [items.currentPage]);
|
||||
|
||||
return (
|
||||
state.loading || categories.length <= 0
|
||||
?
|
||||
<Loader />
|
||||
:
|
||||
<div className={`flex jcc alc w-100 column`}>
|
||||
<div className="graphictoria-nav-splitter"></div>
|
||||
<div className={`row w-60`}>
|
||||
<div className={`col-3 justify-content-center flex-column`}>
|
||||
<div>
|
||||
<h4>Categories:</h4>
|
||||
{categories.map(category=>(
|
||||
<>
|
||||
<Link to={`/catalog/category/${category.id}`}>{category.title}</Link><br/>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
<div className="graphictoria-nav-splitter"></div>
|
||||
<div>
|
||||
<h4>Options:</h4>
|
||||
<div className={`flex flex-column`}>
|
||||
<h6>Search for an item:</h6>
|
||||
<input placeholder={`temp`}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`col justify-content-center`}>
|
||||
{items.items.length <= 0 ? <p>There are currently no items!</p> : null}
|
||||
<div className={`flex flex-row flex-wrap`}>
|
||||
{items.items.map(item=>(
|
||||
<>
|
||||
<Link to={`/item/${item.id}`} className={`flex graphic-post-column col-3`}>
|
||||
<div className={`flex column mb-10 alc`}>
|
||||
[Thumbnail.]
|
||||
</div>
|
||||
<div className={`flex flex-column m-0`}>
|
||||
<div className={`flex row w-fit-content`}><h6 className={`m-0 mr-15 fs13`}>{item.title}</h6></div>
|
||||
<div className={`row fs15 w-fit-content`}>
|
||||
<p className={`w-fit-content`}>${item.current_price}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
{items.items.length >= 1?
|
||||
<div className={`w-100 jcc alc row mt-15`}>
|
||||
{items.currentPage >= 2? <button className={`w-fit-content btn btn-primary mr-15`} onClick={(e)=>{paginateitems(true);}}>Previous Page</button> : null}
|
||||
{items.currentPage < items.meta.last_page? <button className={`w-fit-content btn btn-primary`} onClick={(e)=>{paginateitems(false);}}>Next Page</button> : null}
|
||||
</div> : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Catalog;
|
||||
|
|
@ -73,7 +73,7 @@ const Forum = (props) => {
|
|||
}, [posts.currentPage]);
|
||||
|
||||
return (
|
||||
state.loading
|
||||
state.loading || categories.length <= 0
|
||||
?
|
||||
<Loader />
|
||||
:
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ const Settings = (props) => {
|
|||
</div>
|
||||
<div className="graphictoria-nav-splitter"></div>
|
||||
{validity.error?
|
||||
<div className={`px-5 mb-10 w-60`}>
|
||||
<div className={`error-dialog w-60`}>
|
||||
<div className={`px-5 mb-10 w-60 justify-content-center align-items-center`}>
|
||||
<div className={`error-dialog w-100`}>
|
||||
<p className={`mb-0`}>{validity.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -330,6 +330,7 @@ html {
|
|||
|
||||
.graphictoria-nav-splitter {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px !important;
|
||||
}
|
||||
|
||||
.graphictoria-search, #graphictoria-search-dropdown {
|
||||
|
|
@ -928,10 +929,34 @@ p {
|
|||
margin: 0px !important;
|
||||
}
|
||||
|
||||
.fs10 {
|
||||
font-size: 10px !important;
|
||||
}
|
||||
|
||||
.fs11 {
|
||||
font-size: 11px !important;
|
||||
}
|
||||
|
||||
.fs12 {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.fs13 {
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
.fs14 {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
.fs15 {
|
||||
font-size: 15px !important;
|
||||
}
|
||||
|
||||
.fs16 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
.padding-none {
|
||||
padding: 0px !important
|
||||
}
|
||||
|
|
@ -956,6 +981,26 @@ p {
|
|||
margin-bottom: 15px !important;
|
||||
}
|
||||
|
||||
.mb-5 {
|
||||
margin-bottom: 5px !important;
|
||||
}
|
||||
|
||||
.mt-5 {
|
||||
margin-bottom: 5px !important;
|
||||
}
|
||||
|
||||
.mb-10 {
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
.mt-10 {
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
::marker {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.graphic-post {
|
||||
padding: 1rem 1rem;
|
||||
text-align: start;
|
||||
|
|
@ -968,6 +1013,18 @@ p {
|
|||
align-items: center !important;
|
||||
}
|
||||
|
||||
.graphic-post-column {
|
||||
padding: 1rem 1rem;
|
||||
text-align: start;
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
background-color: #222 !important;
|
||||
border-radius: 0.25px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
.error-dialog {
|
||||
padding: 5px;
|
||||
margin-bottom: 10px;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ Route::get('/fetch/categories', 'Controller@fetchCategories');
|
|||
|
||||
Route::post('/fetch/categories/post', 'Controller@fetchCategoriesFP');
|
||||
|
||||
Route::get('/fetch/categories/catalog', 'Controller@fetchCategoriesCatalog');
|
||||
|
||||
Route::get('/fetch/category/catalog/{id}', 'Controller@fetchCategoryCatalog');
|
||||
|
||||
Route::get('/fetch/category/{id}', 'Controller@fetchCategory');
|
||||
|
||||
Route::get('/fetch/posts/{id}', 'Controller@fetchPosts');
|
||||
|
|
|
|||
Loading…
Reference in New Issue