diff --git a/web/app/Http/Controllers/Controller.php b/web/app/Http/Controllers/Controller.php index 63bfe5c..0b881b8 100644 --- a/web/app/Http/Controllers/Controller.php +++ b/web/app/Http/Controllers/Controller.php @@ -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(); diff --git a/web/app/Models/CatalogCategory.php b/web/app/Models/CatalogCategory.php new file mode 100644 index 0000000..588671a --- /dev/null +++ b/web/app/Models/CatalogCategory.php @@ -0,0 +1,20 @@ +morphMany('App\Models\Item', 'category'); + } + +} diff --git a/web/app/Models/Inventory.php b/web/app/Models/Inventory.php new file mode 100644 index 0000000..f7bdf38 --- /dev/null +++ b/web/app/Models/Inventory.php @@ -0,0 +1,19 @@ +belongsTo(Item::class); + } + +} diff --git a/web/app/Models/Item.php b/web/app/Models/Item.php new file mode 100644 index 0000000..935f698 --- /dev/null +++ b/web/app/Models/Item.php @@ -0,0 +1,15 @@ +id)->first(); return $staff; } + + public function inventory() { + return $this->morphMany('App\Models\Inventory', 'owner'); + } } diff --git a/web/database/migrations/2021_12_16_011849_create_users_table.php b/web/database/migrations/2021_12_16_011849_create_users_table.php index f91f29d..3dd6eb8 100644 --- a/web/database/migrations/2021_12_16_011849_create_users_table.php +++ b/web/database/migrations/2021_12_16_011849_create_users_table.php @@ -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(); }); diff --git a/web/database/migrations/2022_03_23_215614_create_items_table.php b/web/database/migrations/2022_03_23_215614_create_items_table.php new file mode 100644 index 0000000..ce26c93 --- /dev/null +++ b/web/database/migrations/2022_03_23_215614_create_items_table.php @@ -0,0 +1,40 @@ +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'); + } +} diff --git a/web/database/migrations/2022_03_23_215624_create_inventories_table.php b/web/database/migrations/2022_03_23_215624_create_inventories_table.php new file mode 100644 index 0000000..00387e9 --- /dev/null +++ b/web/database/migrations/2022_03_23_215624_create_inventories_table.php @@ -0,0 +1,36 @@ +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'); + } +} diff --git a/web/database/migrations/2022_03_23_215847_create_catalog_categories_table.php b/web/database/migrations/2022_03_23_215847_create_catalog_categories_table.php new file mode 100644 index 0000000..c0c259c --- /dev/null +++ b/web/database/migrations/2022_03_23_215847_create_catalog_categories_table.php @@ -0,0 +1,33 @@ +id(); + $table->string('title'); + $table->string('description'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('catalog_categories'); + } +} diff --git a/web/resources/js/components/Navbar.js b/web/resources/js/components/Navbar.js index ce7099e..aba49c0 100644 --- a/web/resources/js/components/Navbar.js +++ b/web/resources/js/components/Navbar.js @@ -51,13 +51,16 @@ const Navbar = (props) => { <> {props.user? -
  • - - -
  • : Login / Sign up} +
    +
    Bank: ${props.user.bank}
    +
  • + + +
  • +
    : Login / Sign up} : null diff --git a/web/resources/js/layouts/App.js b/web/resources/js/layouts/App.js index 92c6667..7735033 100644 --- a/web/resources/js/layouts/App.js +++ b/web/resources/js/layouts/App.js @@ -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 = () => { + + + + + + + + diff --git a/web/resources/js/pages/Catalog.js b/web/resources/js/pages/Catalog.js new file mode 100644 index 0000000..15c1b3e --- /dev/null +++ b/web/resources/js/pages/Catalog.js @@ -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 + ? + + : +
    +
    +
    +
    +
    +

    Categories:

    + {categories.map(category=>( + <> + {category.title}
    + + ))} +
    +
    +
    +

    Options:

    +
    +
    Search for an item:
    + +
    +
    +
    +
    + {items.items.length <= 0 ?

    There are currently no items!

    : null} +
    + {items.items.map(item=>( + <> + +
    + [Thumbnail.] +
    +
    +
    {item.title}
    +
    +

    ${item.current_price}

    +
    +
    + + + ))} +
    + {items.items.length >= 1? +
    + {items.currentPage >= 2? : null} + {items.currentPage < items.meta.last_page? : null} +
    : null} +
    +
    +
    + ); +} + +export default Catalog; diff --git a/web/resources/js/pages/Forum.js b/web/resources/js/pages/Forum.js index d5d1a1a..001c140 100644 --- a/web/resources/js/pages/Forum.js +++ b/web/resources/js/pages/Forum.js @@ -73,7 +73,7 @@ const Forum = (props) => { }, [posts.currentPage]); return ( - state.loading + state.loading || categories.length <= 0 ? : diff --git a/web/resources/js/pages/Settings.js b/web/resources/js/pages/Settings.js index c752109..3647fe5 100644 --- a/web/resources/js/pages/Settings.js +++ b/web/resources/js/pages/Settings.js @@ -68,8 +68,8 @@ const Settings = (props) => {
    {validity.error? -
    -
    +
    +

    {validity.message}

    diff --git a/web/resources/sass/Graphictoria.scss b/web/resources/sass/Graphictoria.scss index 65ce360..143fa64 100644 --- a/web/resources/sass/Graphictoria.scss +++ b/web/resources/sass/Graphictoria.scss @@ -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; diff --git a/web/routes/apis.php b/web/routes/apis.php index b720633..bb80f0c 100644 --- a/web/routes/apis.php +++ b/web/routes/apis.php @@ -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');