From dcd43fa9de3aac68c2a6881aa8b92eeb6dd52d1d Mon Sep 17 00:00:00 2001 From: Firesieht Date: Sat, 8 Oct 2022 19:23:31 +0300 Subject: [PATCH 1/3] add marketplace --- src/admin/adminMarket/index.tsx | 42 ++++++++---- src/admin/adminMarketCard/adminMarketCard.css | 4 +- src/admin/adminMarketCard/index.tsx | 19 +++--- src/admin/adminMarketPopUp/index.tsx | 10 ++- src/admin/index.tsx | 15 +---- src/app/admin/adminSlice.ts | 64 ++++++++++++++----- src/app/interfaces.ts | 2 +- src/components/Header/Header.css | 1 + src/components/fileUploader.tsx | 24 ++++--- 9 files changed, 108 insertions(+), 73 deletions(-) diff --git a/src/admin/adminMarket/index.tsx b/src/admin/adminMarket/index.tsx index 2ee3138..4c17077 100644 --- a/src/admin/adminMarket/index.tsx +++ b/src/admin/adminMarket/index.tsx @@ -1,23 +1,18 @@ import React, { useState } from "react" -import { getProducts, getUser } from "../../app/admin/adminSlice"; +import { addProduct, addProducts, fetchAddProduct, getProducts, getUser } from "../../app/admin/adminSlice"; import { RootAdminState } from "../../app/adminStore"; -import { useAppSelector } from "../../app/hooks"; +import { adminFetcher, useAppDispatch, useAppSelector } from "../../app/hooks"; import { Header } from "../../components/Header"; import { AdminMarketCard } from "../adminMarketCard"; import "./adminMarket.css" -import { - BrowserRouter as Router, - Route, - Routes, - Link - } from "react-router-dom"; -import { AdminMarketPopUp } from "../adminMarketPopUp"; +import { ProductIE } from "../../app/interfaces"; export const AdminMarket:React.FC = () =>{ - const [opened, setOpened] = useState(false); + const [first, setFirst] = useState(true) + let user = useAppSelector((state:RootAdminState)=>getUser(state)) let cards: JSX.Element[] = [] - let products = useAppSelector( + let prod = useAppSelector( (state: RootAdminState)=>getProducts(state)).forEach( product=>cards.push({ cost={product.cost} id={product.id} >)) - + let products = useAppSelector((state:RootAdminState)=>getProducts(state)) + + let dispatch = useAppDispatch() + + if (products.length == 0 && first ){ + setFirst(false) + adminFetcher.get("marketplace/product/").then( + (response)=>{ + dispatch(addProducts( + response.data.map((params:any)=> + ({ + name: params.name, + description:params.description, + image: params.image_cropped, + cost:Number(params.price), + id:params.slug + } as ProductIE) + ) + )) + } + ) + } + + return(
= (props) =>{ return(
- -
- -
{props.cost}
+ +
+
+ +
{props.cost}
+
+
{props.name}
+
{props.description.split(" ").slice(0,6).join(" ")}
+ +
-
{props.name}
-
{props.description}
- - +
) } \ No newline at end of file diff --git a/src/admin/adminMarketPopUp/index.tsx b/src/admin/adminMarketPopUp/index.tsx index 4692ba5..bb8aaed 100644 --- a/src/admin/adminMarketPopUp/index.tsx +++ b/src/admin/adminMarketPopUp/index.tsx @@ -11,7 +11,7 @@ import { Header } from "../../components/Header" export const AdminMarketPopUp:React.FC = () =>{ let {id} = useParams() - let product = useAppSelector((state: RootAdminState)=>getProductByID(state, Number(id))) + let product = useAppSelector((state: RootAdminState)=>getProductByID(state, id as string)) const [cost, setCost] = useState(product.cost) const [name, setName] = useState(product.name) const [descr, setDescr] = useState(product.description) @@ -20,14 +20,12 @@ export const AdminMarketPopUp:React.FC = () =>{ let dispatch = useAppDispatch() let navigate = useNavigate() const onSave = () =>{ - console.log("cocb") fetchChangeProduct(dispatch, { cost: cost, name: name, - description: descr, - id:product.id, - image: product.image - } as ProductIE) + descr: descr, + id: product.id + }) navigate("/admin/market") } diff --git a/src/admin/index.tsx b/src/admin/index.tsx index 624a983..3bc544b 100644 --- a/src/admin/index.tsx +++ b/src/admin/index.tsx @@ -8,21 +8,8 @@ import { RootAdminState } from "../app/adminStore"; import { Header } from "../components/Header"; export const AdminPage:React.FC = () => { - const [respProducts, setRespProducts] = useState([-1 as any]) - let products = useAppSelector((state:RootAdminState)=>getProducts(state)) - let user = useAppSelector((state:RootAdminState)=>getUser(state)) - let dispatch = useAppDispatch() - if (products.length == 0){ - adminFetcher.get("marketplace/product/").then( - (response)=> setRespProducts(response.data as any) - ) - } - if (respProducts[0] != -1){ - respProducts.forEach((product)=>{ - fetchAddProduct(dispatch, product) - }) - } + let user = useAppSelector((state:RootAdminState)=>getUser(state)) return( diff --git a/src/app/admin/adminSlice.ts b/src/app/admin/adminSlice.ts index 88c0780..21042a3 100644 --- a/src/app/admin/adminSlice.ts +++ b/src/app/admin/adminSlice.ts @@ -32,9 +32,16 @@ const adminSlice = createSlice( state.user.balance = state.user.balance - action.payload }, addProduct(state, action: PayloadAction){ - state.market.products = state.market.products.concat([action.payload]) + if(state.market.products.indexOf(action.payload) == -1){ + state.market.products = state.market.products.concat([action.payload]) + } }, - delProduct(state, action:PayloadAction){ + addProducts(state, action: PayloadAction){ + if(state.market.products.length == 0){ + state.market.products = state.market.products.concat(action.payload) + } + }, + delProduct(state, action:PayloadAction){ let products = state.market.products let ind = 0 products.forEach((product, index)=>{ @@ -47,6 +54,7 @@ const adminSlice = createSlice( }, changeProduct(state, action:PayloadAction){ let products = state.market.products + console.log(action.payload) products.forEach((product,index)=>{ if (product.id == action.payload.id){ products[index] = action.payload @@ -64,29 +72,50 @@ export async function fetchSendCoins(dispatch:AppAdminDispatch, params:{userID:n dispatch(sendCoins(params.amount)) } -export async function fetchAddProduct(dispatch:AppAdminDispatch, params:{image: FormData, descr: string, name:string, cost:number}) { +export async function fetchAddProduct(dispatch:AppAdminDispatch, params:{image: File, descr: string, name:string, cost:number}) { //тут идет фетч - let data = { - image: "", - description: params.descr, - name: params.name, - cost: params.cost, - id: params.cost - } as ProductIE //vмоковая даата - adminFetcher.post("marketplace/product/", { + const formData = new FormData() + formData.append("name",params.name) + formData.append("description",params.descr) + formData.append("image", params.image) + formData.append("price",params.cost.toString()) + adminFetcher.post("marketplace/product/", formData).then((response)=>{ + dispatch(addProduct({ + name: response.data.name, + description:response.data.description, + image: response.data.image_cropped, + cost:Number(response.data.price), + id:response.data.slug + } as ProductIE)) }) - dispatch(addProduct(data)) + } -export async function fetchDelProduct(dispatch:AppAdminDispatch, id:number) { +export async function fetchDelProduct(dispatch:AppAdminDispatch, id:string) { //тут идет фетч - dispatch(delProduct(id)) + adminFetcher.delete("marketplace/product/"+id).then(()=>dispatch(delProduct(id))) + } -export async function fetchChangeProduct(dispatch:AppAdminDispatch, params:ProductIE) { - dispatch(changeProduct(params)) +export async function fetchChangeProduct(dispatch:AppAdminDispatch, params:{id:string, descr: string, name:string, cost:number}) { + const formData = new FormData() + formData.append("name",params.name) + formData.append("description",params.descr) + formData.append("price",params.cost.toString()) + adminFetcher.patch("marketplace/product/" + params.id, formData).then((response)=>{ + dispatch(delProduct(params.id)) + dispatch(addProduct({ + name: response.data.name, + description:response.data.description, + image: response.data.image_cropped, + cost:Number(response.data.price), + id:response.data.slug + } as ProductIE)) + + }) + } export const getProducts = createSelector( @@ -95,7 +124,7 @@ export const getProducts = createSelector( ) export const getProductByID = createSelector( - (state:RootAdminState, id:number) => state.adminSlice.market.products.filter((product)=>product.id == id)[0], + (state:RootAdminState, id:string) => state.adminSlice.market.products.filter((product)=>product.id == id)[0], (field)=>field ) @@ -113,6 +142,7 @@ export const { addProduct, delProduct, changeProduct, + addProducts } = adminSlice.actions export default adminSlice.reducer \ No newline at end of file diff --git a/src/app/interfaces.ts b/src/app/interfaces.ts index e65eb84..6efc594 100644 --- a/src/app/interfaces.ts +++ b/src/app/interfaces.ts @@ -42,7 +42,7 @@ export interface ProductIE{ description:string, image: string, cost: number, - id: number, + id: string, } export enum SortTypes{ diff --git a/src/components/Header/Header.css b/src/components/Header/Header.css index 10c8220..4e8f5e6 100644 --- a/src/components/Header/Header.css +++ b/src/components/Header/Header.css @@ -15,6 +15,7 @@ line-height: 24px; color: #FFFFFF; + z-index: 1000; } .links{ display: flex; diff --git a/src/components/fileUploader.tsx b/src/components/fileUploader.tsx index e65bf8e..07cd6a2 100644 --- a/src/components/fileUploader.tsx +++ b/src/components/fileUploader.tsx @@ -12,27 +12,25 @@ export const FileUploader:React.FC = (data) =>{ const props = { name: 'file', - action: host + '/api/', + action: "", headers: { authorization: 'authorization-text', }, - - onChange(info:any) { - if (info.file.status !== 'uploading') { - } - - if (info.file.status === 'done') { - data.onResponse(info.file.response) - message.success(`${info.file.name} file uploaded successfully`); - } else if (info.file.status === 'error') { - message.error(`${info.file.name} file upload failed.`); + beforeUpload: (file:File) => { + const isPNG = file.type === 'image/png'; + if (!isPNG) { + message.error(`${file.name} is not a png file`); } + data.onResponse(file) + return isPNG || Upload.LIST_IGNORE; + }, + }; return ( - - + + ); } \ No newline at end of file From fa344c09e4942b0b5815820f485bf672414d1d7e Mon Sep 17 00:00:00 2001 From: Firesieht Date: Sun, 9 Oct 2022 01:47:55 +0300 Subject: [PATCH 2/3] add ALLL --- public/gear.svg | 3 + public/respect.svg | 10 + src/admin/addAdminMarketCard/index.tsx | 8 +- src/admin/addUser/index.tsx | 88 +++++++++ src/admin/adminClans/adminClans.css | 0 src/admin/adminClans/index.tsx | 101 ++++++++++ src/admin/adminMarket/index.tsx | 8 +- src/admin/adminUserCard/adminUserCard.css | 34 ++++ src/admin/adminUserCard/index.tsx | 84 ++++++++ src/admin/userTable/index.tsx | 224 ++++++++++++++++++++++ src/admin/userTable/userTable.css | 17 ++ src/app/admin/adminSlice.ts | 114 ++++++++++- src/app/hooks.ts | 2 +- src/app/interfaces.ts | 10 +- src/index.tsx | 9 + 15 files changed, 696 insertions(+), 16 deletions(-) create mode 100644 public/gear.svg create mode 100644 public/respect.svg create mode 100644 src/admin/addUser/index.tsx create mode 100644 src/admin/adminClans/adminClans.css create mode 100644 src/admin/adminClans/index.tsx create mode 100644 src/admin/adminUserCard/adminUserCard.css create mode 100644 src/admin/adminUserCard/index.tsx create mode 100644 src/admin/userTable/index.tsx create mode 100644 src/admin/userTable/userTable.css diff --git a/public/gear.svg b/public/gear.svg new file mode 100644 index 0000000..3e563cd --- /dev/null +++ b/public/gear.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/respect.svg b/public/respect.svg new file mode 100644 index 0000000..a7180cb --- /dev/null +++ b/public/respect.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/admin/addAdminMarketCard/index.tsx b/src/admin/addAdminMarketCard/index.tsx index 7814332..ba85bf1 100644 --- a/src/admin/addAdminMarketCard/index.tsx +++ b/src/admin/addAdminMarketCard/index.tsx @@ -35,6 +35,10 @@ export const AddAdminMarketProduct:React.FC = () =>{ return(
{ link:"/admin/market/add", name:"Cоздать товар (NFT)" }, - { - link:"/admin/users", - name:"Участники" - } ]} name={user.name}>
diff --git a/src/admin/addUser/index.tsx b/src/admin/addUser/index.tsx new file mode 100644 index 0000000..ed87661 --- /dev/null +++ b/src/admin/addUser/index.tsx @@ -0,0 +1,88 @@ +import { Button, Input } from "antd"; +import { Dropdown, Menu, Space } from 'antd'; + +import React, { useState } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import { fetchAddEmployer, fetchChangeEmployer, fetchDelEmployer, getEmployerByTg } from "../../app/admin/adminSlice"; +import { RootAdminState } from "../../app/adminStore"; +import { useAppDispatch, useAppSelector } from "../../app/hooks"; +import "../adminUserCard/adminUserCard.css" + +export const AddUser:React.FC = () => { + let dispatch = useAppDispatch() + let navigate = useNavigate() + const [type, setType] = useState("WORKER") //WORKER HR ADMIN + const [salary, setSalary] = useState("10") + const [tg, setTg] = useState("") + const [pass, setPass] = useState("") + const [name, setName] = useState("") + const [respect, setrespect] = useState("100") + const [command, setcommand] = useState("") + + + + const onSave = () =>{ + console.log(type) + fetchAddEmployer(dispatch,{ + name:name, + salary:salary, + respect: respect, + type: type, + pass:pass, + tg:tg, + command: command + }) + alert("Пользователь добавлен!") + navigate("/admin/users") + } + + + + return( +
+
+
+ Создание пользователя +
+
+
+
Telegram
+ setTg(e.target.value)} placeholder="Telegram"> +
+
+
Роль
+ +
+
+
ФИО
+ setName(e.target.value)} placeholder="ФИО"> +
+
+
Пароль
+ setPass(e.target.value)} placeholder="ФИО"> +
+ +
+
Зарплата
+ setSalary(e.target.value)} placeholder="баланс"> +
+
+
Респект
+ setrespect(e.target.value)} placeholder="респект"> +
+
+
Команда
+ setcommand(e.target.value)} placeholder="команда"> +
+
+
+ +
+
+
+ ); +} \ No newline at end of file diff --git a/src/admin/adminClans/adminClans.css b/src/admin/adminClans/adminClans.css new file mode 100644 index 0000000..e69de29 diff --git a/src/admin/adminClans/index.tsx b/src/admin/adminClans/index.tsx new file mode 100644 index 0000000..87f92e8 --- /dev/null +++ b/src/admin/adminClans/index.tsx @@ -0,0 +1,101 @@ +import "./adminClans.css" +import { Button, Space, Table, Tag } from 'antd'; +import { useNavigate, useParams } from "react-router-dom"; +import { getClanByName, getEmployers } from "../../app/admin/adminSlice"; +import { useAppSelector } from "../../app/hooks"; +import type { ColumnsType } from 'antd/es/table'; +import { RootAdminState } from "../../app/adminStore"; + + +interface DataTypeIE{ + key:string, + name:string, + telegram:string, + respect:number, + balance:number, + speciality: string, +} + + +export const AdminClans:React.FC = () =>{ + let {name} = useParams() + let clan = useAppSelector((state)=>getClanByName(state, name as string)) + let navigator = useNavigate() + const collator = new Intl.Collator('ru'); + let users = useAppSelector((state:RootAdminState)=>getEmployers(state)) + const data:DataTypeIE[] = [] + + const columns: ColumnsType = [ + { + title: "+", + key: "action", + render: (_, record) =>( + navigator("/admin/users/" + record.key)} src="/gear.svg"> + ) + }, + { + title: 'ФИО', + dataIndex: 'name', + key: 'name', + defaultSortOrder: 'descend', + sorter: (a, b) => collator.compare(a.name, b.name) , + }, + { + title: 'Telegram', + dataIndex: 'telegram', + key: 'telegram', + sorter: (a, b) => collator.compare(a.telegram, b.telegram) , + + }, + { + title: 'Респект', + dataIndex: 'respect', + key: 'respect', + sorter: (a, b) => a.respect - b.respect, + render: text=>
{text + " "}
+ }, + { + title: 'Баланс', + dataIndex: 'balance', + key: 'balance', + sorter: (a, b) => a.balance - b.balance, + + render: text=>
{text + " "}
+ }, + { + title: 'Специальность', + dataIndex: 'speciality', + key: 'speciality', + sorter: (a, b) => collator.compare(a.speciality, b.speciality) , + render: text=> + {text} + + }, + ] + + if (users.length > 0){ + users.forEach((user)=>{ + data.push( + { + name: user.name, + balance: user.balance, + command: user.command, + speciality: user.jobTittle, + key: user.telegramID, + telegram: user.telegramID, + respect: user.respect, + } as DataTypeIE + ) + }) + + } + return( +
+
+
Участники клана {name}
+ + + + + ); +} \ No newline at end of file diff --git a/src/admin/adminMarket/index.tsx b/src/admin/adminMarket/index.tsx index 4c17077..c420c54 100644 --- a/src/admin/adminMarket/index.tsx +++ b/src/admin/adminMarket/index.tsx @@ -48,6 +48,10 @@ export const AdminMarket:React.FC = () =>{ return(
{ link:"/admin/market/add", name:"Cоздать товар (NFT)" }, - { - link:"/admin/users", - name:"Участники" - } ]} name={user.name}>
diff --git a/src/admin/adminUserCard/adminUserCard.css b/src/admin/adminUserCard/adminUserCard.css new file mode 100644 index 0000000..5a14102 --- /dev/null +++ b/src/admin/adminUserCard/adminUserCard.css @@ -0,0 +1,34 @@ +.userCard{ + padding-top: 200px; + width: 100%; + height: 100vh; + background: linear-gradient(85.91deg, #096DD9 0%, #40A9FF 100%); + display: flex; + flex-direction: column; + align-items: center; +} + +.userCardWrapper{ + display: flex; + flex-direction: column; + gap:15px; + justify-content: flex-start; + align-items: flex-start; +} + +.nameText{ + font-weight: 400; + font-size: 16px; + line-height: 24px; + color: rgba(0, 0, 0, 0.85) +} +.fieldText{ + font-size: 14px; + line-height: 22px; + color: rgba(0, 0, 0, 0.45); +} +.btnWrapper{ + display: flex; + flex-direction: row; + gap: 25px +} \ No newline at end of file diff --git a/src/admin/adminUserCard/index.tsx b/src/admin/adminUserCard/index.tsx new file mode 100644 index 0000000..7efff1b --- /dev/null +++ b/src/admin/adminUserCard/index.tsx @@ -0,0 +1,84 @@ +import { Button, Input } from "antd"; +import React, { useState } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import { fetchChangeEmployer, fetchDelEmployer, getEmployerByTg } from "../../app/admin/adminSlice"; +import { RootAdminState } from "../../app/adminStore"; +import { useAppDispatch, useAppSelector } from "../../app/hooks"; +import "./adminUserCard.css" + +export const AdminUserCard:React.FC = () => { + let {tg} = useParams() + let user = useAppSelector((state: RootAdminState) => getEmployerByTg(state, tg as string)) + let dispatch = useAppDispatch() + let navigate = useNavigate() + + const [name, setName] = useState(user.name) + const [balance, setbalance] = useState(user.balance) + const [respect, setrespect] = useState(user.respect) + const [command, setcommand] = useState(user.name) + const [jobTittle, setjobTittle] = useState(user.jobTittle) + + + const onDelete = () =>{ + fetchDelEmployer(dispatch, user.telegramID) + } + + const onSave = () =>{ + fetchChangeEmployer(dispatch,{ + name:name, + balance:balance, + respect: respect, + speciality: jobTittle, + tg:user.telegramID + }) + alert("Данные сохранены!") + navigate("/admin/users") + } + return( +
+
+
+ Редактирование пользователя: {user.name} +
+
+
+
Telegram
+
{user.telegramID}
+
+
+
Кошелек
+
{user.wallet}
+
+
+
Роль
+
{user.role}
+
+
+
ФИО
+ setName(e.target.value)} placeholder="ФИО"> +
+
+
Баланс
+ setbalance(Number(e.target.value))} placeholder="баланс"> +
+
+
Респект
+ setrespect(Number(e.target.value))} placeholder="респект"> +
+
+
Команда
+ setcommand(e.target.value)} placeholder="команда"> +
+
+
Специальность
+ setjobTittle(e.target.value)} placeholder="специальность"> +
+
+
+ + +
+
+
+ ); +} \ No newline at end of file diff --git a/src/admin/userTable/index.tsx b/src/admin/userTable/index.tsx new file mode 100644 index 0000000..f7dbfd6 --- /dev/null +++ b/src/admin/userTable/index.tsx @@ -0,0 +1,224 @@ +import { Button, Space, Table, Tag } from 'antd'; +import type { ColumnsType } from 'antd/es/table'; +import React, { useReducer, useState } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import { clearScreenDown } from 'readline'; +import { getClans, getEmployers, getUser, setClans, setEmployers } from '../../app/admin/adminSlice'; +import { RootAdminState } from '../../app/adminStore'; +import { adminFetcher, useAppDispatch, useAppSelector } from '../../app/hooks'; +import { ClanIE, EmployerIE } from '../../app/interfaces'; +import { Header } from '../../components/Header'; +import "./userTable.css" + +interface DataTypeIE{ + key:string, + name:string, + telegram:string, + command:string, + respect:number, + balance:number, + speciality: string, +} +interface ClanColumnsIE{ + key: string, + name: string, + tg: string, + members: number +} + + +export const UserTable:React.FC = () =>{ + let [clans, setclans] = useState(false) + + let navigator = useNavigate() + const collator = new Intl.Collator('ru'); + let user = useAppSelector((state:RootAdminState)=>getUser(state)) + const clanColums:ColumnsType = [ + { + title: "+", + key: "action", + render: (_, record) =>( + navigator("/admin/clans/" + record.name)} src="/gear.svg"> + ) + }, + { + title: 'Название клана', + dataIndex: 'name', + key: 'name', + defaultSortOrder: 'descend', + sorter: (a, b) => collator.compare(a.name, b.name) , + }, + { + title: 'Telegram клана', + dataIndex: 'name', + key: 'name', + render: (_, record) => (
@{record.name.split(" ").join("")}
), + sorter: (a, b) => collator.compare(a.name, b.name) , + }, + { + title: 'Количество участников', + dataIndex: 'members', + key: 'members', + sorter: (a, b) => a.members - b.members , + }, + { + title: 'Участники', + dataIndex: 'members', + key: 'members', + render: (_, record) => (
Посмотреть
), + sorter: (a, b) => collator.compare(a.name, b.name) , + }, + ] + const columns: ColumnsType = [ + { + title: "+", + key: "action", + render: (_, record) =>( + navigator("/admin/users/" + record.key)} src="/gear.svg"> + ) + }, + { + title: 'ФИО', + dataIndex: 'name', + key: 'name', + defaultSortOrder: 'descend', + sorter: (a, b) => collator.compare(a.name, b.name) , + }, + { + title: 'Telegram', + dataIndex: 'telegram', + key: 'telegram', + sorter: (a, b) => collator.compare(a.telegram, b.telegram) , + + }, + { + title: 'Название клана', + dataIndex: 'command', + key: 'command', + sorter: (a, b) => Number(a.command) - Number(b.command) , + + }, + { + title: 'Респект', + dataIndex: 'respect', + key: 'respect', + sorter: (a, b) => a.respect - b.respect, + render: text=>
{text + " "}
+ }, + { + title: 'Баланс', + dataIndex: 'balance', + key: 'balance', + sorter: (a, b) => a.balance - b.balance, + + render: text=>
{text + " "}
+ }, + { + title: 'Специальность', + dataIndex: 'speciality', + key: 'speciality', + sorter: (a, b) => collator.compare(a.speciality, b.speciality) , + render: text=> + {text} + + }, + ] + + let dispatch = useAppDispatch() + + const data:DataTypeIE[] = [] + const clanData:ClanColumnsIE[] = [] + + let users = useAppSelector((state:RootAdminState)=>getEmployers(state)) + let clansData = useAppSelector((state:RootAdminState)=>getClans(state)) + if (users.length == 0){ + adminFetcher.get("users/").then((response)=>{ + dispatch(setEmployers(response.data.map(((user:any)=>({ + name: user.name, + wallet: user.wallet_public_key, + telegramID: user.telegram, + command: user.command, + role: user.type, + respect: user.respect, + balance: user.salary, + jobTittle: user.department, + }) as EmployerIE )))) + }) + adminFetcher.get("season/clans/").then((response:any)=>{ + dispatch(setClans( + response.data.map((clan:any)=>({ + name: clan.name, + users: clan.users.map(((user:any)=>({ + name: user.name, + wallet: user.wallet_public_key, + telegramID: user.telegram, + command: user.command, + role: user.type, + respect: user.respect, + balance: user.salary, + jobTittle: user.department, + }) )) + } as ClanIE)) + )) + }) + } + if (users.length > 0){ + users.forEach((user)=>{ + data.push( + { + name: user.name, + balance: user.balance, + command: user.command, + speciality: user.jobTittle, + key: user.telegramID, + telegram: user.telegramID, + respect: user.respect, + } as DataTypeIE + ) + }) + clansData.forEach((clan)=>{ + clanData.push({ + key:clan.name, + name:clan.name, + tg: clan.name, + members:clan.users.length + } as ClanColumnsIE) + }) + } + + return( +
+
+
+
Участники VTB Games
+
+ + + + + + +
+ { + clans?
:
+ } + + + + ); +} \ No newline at end of file diff --git a/src/admin/userTable/userTable.css b/src/admin/userTable/userTable.css new file mode 100644 index 0000000..5c1bc49 --- /dev/null +++ b/src/admin/userTable/userTable.css @@ -0,0 +1,17 @@ +.userTable{ + padding-top: 200px; + width: 100%; + height: 100vh; + background: linear-gradient(85.91deg, #096DD9 0%, #40A9FF 100%); + display: flex; + flex-direction: column; + align-items: center; +} + +.userTableWrapper{ + display: flex; + flex-direction: column; + gap:15px; + justify-content: flex-start; + align-items: flex-start; +} \ No newline at end of file diff --git a/src/app/admin/adminSlice.ts b/src/app/admin/adminSlice.ts index 21042a3..fd5904d 100644 --- a/src/app/admin/adminSlice.ts +++ b/src/app/admin/adminSlice.ts @@ -1,9 +1,10 @@ import { createAsyncThunk, createSlice, createSelector, PayloadAction } from '@reduxjs/toolkit' import { stat } from 'fs' -import { Market, Roles, SortTypes, UserIE, ProductIE} from '../interfaces' +import { Market, Roles, SortTypes, UserIE, ProductIE, EmployerIE, ClanIE} from '../interfaces' import { AppAdminDispatch, RootAdminState } from '../adminStore' import { adminFetcher, useAppDispatch } from '../hooks' import { host, token } from '../consts' +import { triggerAsyncId } from 'async_hooks' @@ -13,14 +14,16 @@ const initState = { user: { wallet:"123214", balance: 100, - id:1, + id:"1", role:Roles.admin, name:"Firesieht" } as UserIE, //потом достается запросом market: { sortType: SortTypes.sortByPriceSmaller, products: [] - } as Market // потом достается запросом + } as Market, // потом достается запросом + employers: [] as EmployerIE[], + clans: [] as ClanIE[] } const adminSlice = createSlice( @@ -28,6 +31,28 @@ const adminSlice = createSlice( name: "adminSlice", initialState: initState, reducers:{ + setClans(state, action:PayloadAction){ + state.clans = action.payload + }, + setEmployers(state, action:PayloadAction){ + state.employers = action.payload + }, + addEmployer(state, action:PayloadAction){ + if(state.employers.length == 0){ + state.employers = state.employers.concat([action.payload]) + } + }, + delEmployer(state, action:PayloadAction){ + let employers = state.employers + let ind = 0 + employers.forEach((employer, index)=>{ + if (employer.telegramID == action.payload){ + ind = index + } + }) + employers.splice(ind, 1) + state.employers = employers + }, sendCoins(state, action: PayloadAction){ state.user.balance = state.user.balance - action.payload }, @@ -52,9 +77,17 @@ const adminSlice = createSlice( products.splice(ind, 1) state.market.products = products }, + changeEmployer(state, action:PayloadAction){ + let employers = state.employers + employers.forEach((product,index)=>{ + if (product.telegramID == action.payload.telegramID){ + employers[index] = action.payload + } + }) + state.employers = employers + }, changeProduct(state, action:PayloadAction){ let products = state.market.products - console.log(action.payload) products.forEach((product,index)=>{ if (product.id == action.payload.id){ products[index] = action.payload @@ -118,6 +151,55 @@ export async function fetchChangeProduct(dispatch:AppAdminDispatch, params:{id:s } +export async function fetchAddEmployer(dispatch:AppAdminDispatch, params:{pass:string, name: string, respect: string, salary:string, command:string, tg:string, type: string}) { + const formData = new FormData() + formData.append("name",params.name) + formData.append("type",params.type) + formData.append("respect", params.respect.toString()) + formData.append("salary",params.salary.toString()) + formData.append("telegram",params.tg) + formData.append("command", params.command) + formData.append("password", params.pass) + adminFetcher.post("users/", formData).then((user)=>{ + dispatch(addEmployer({ + name: user.data.name, + wallet: user.data.wallet_public_key, + telegramID: user.data.telegram, + command: user.data.command, + role: user.data.type, + respect: user.data.respect, + balance: user.data.salary, + jobTittle: user.data.department, + } as EmployerIE)) + + }) +} + +export async function fetchDelEmployer(dispatch:AppAdminDispatch, tg:string) { + adminFetcher.delete("users/"+tg).then(()=>dispatch(delProduct(tg))) +} + +export async function fetchChangeEmployer(dispatch:AppAdminDispatch, params:{name: string, respect: number, balance:number, speciality:string, tg:string}) { + const formData = new FormData() + formData.append("name",params.name) + formData.append("respect", params.respect.toString()) + formData.append("salary",params.balance.toString()) + adminFetcher.patch("users/" + params.tg, formData).then((user)=>{ + console.log(user) + dispatch(changeEmployer({ + name: user.data.name, + wallet: user.data.wallet_public_key, + telegramID: user.data.telegram, + command: user.data.command, + role: user.data.type, + respect: user.data.respect, + balance: user.data.salary, + jobTittle: user.data.department, + } as EmployerIE)) + + }) +} + export const getProducts = createSelector( (state:RootAdminState) => state.adminSlice.market.products, (field)=>field @@ -128,6 +210,11 @@ export const getProductByID = createSelector( (field)=>field ) +export const getEmployerByTg = createSelector( + (state:RootAdminState, tg:string) => state.adminSlice.employers.filter((product)=>product.telegramID == tg)[0], + (field)=>field +) + export const getSortType = createSelector( (state:RootAdminState) => state.adminSlice.market.sortType, (field)=>field @@ -136,13 +223,30 @@ export const getUser = createSelector( (state:RootAdminState) => state.adminSlice.user, (field)=>field ) +export const getEmployers = createSelector( + (state:RootAdminState) => state.adminSlice.employers, + (field)=>field +) +export const getClans = createSelector( + (state:RootAdminState) => state.adminSlice.clans, + (field)=>field +) +export const getClanByName = createSelector( + (state:RootAdminState, name: string) => state.adminSlice.clans.filter((clan)=>clan.name == name)[0], + (field)=>field +) export const { sendCoins, addProduct, delProduct, changeProduct, - addProducts + addProducts, + setEmployers, + addEmployer, + delEmployer, + changeEmployer, + setClans } = adminSlice.actions export default adminSlice.reducer \ No newline at end of file diff --git a/src/app/hooks.ts b/src/app/hooks.ts index 350cd1c..4ea28b1 100644 --- a/src/app/hooks.ts +++ b/src/app/hooks.ts @@ -9,7 +9,7 @@ export const useAppSelector: TypedUseSelectorHook = useSelector; export const adminFetcher = axios.create( { baseURL: host, - timeout: 1000, + timeout: 5000, headers: { Authorization: 'Bearer ' + token } diff --git a/src/app/interfaces.ts b/src/app/interfaces.ts index 6efc594..a9aafeb 100644 --- a/src/app/interfaces.ts +++ b/src/app/interfaces.ts @@ -14,7 +14,6 @@ export enum Specialities{ export interface UserIE{ wallet:string, - id:number role:Roles balance: number, name:string, @@ -23,8 +22,10 @@ export interface UserIE{ export interface EmployerIE extends UserIE{ - jobTittle:Specialities, + jobTittle:string, respect: number, + telegramID: string, + command: string, } @@ -55,3 +56,8 @@ export interface Market{ sortType: SortTypes, products: ProductIE[], } + +export interface ClanIE{ + name:string, + users:UserIE[] +} \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index 392ee03..375d983 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -17,6 +17,10 @@ import { Link, Routes } from "react-router-dom"; +import { UserTable } from './admin/userTable'; +import { AdminUserCard } from './admin/adminUserCard'; +import { AdminClans } from './admin/adminClans'; +import { AddUser } from './admin/addUser'; const container = document.getElementById('root')!; const root = createRoot(container); @@ -27,6 +31,11 @@ const router = createBrowserRouter( }> }> }> + }> + }> + }> + }> + From 03e7393ab8986b63e46f250db13902534dd37aca Mon Sep 17 00:00:00 2001 From: Firesieht Date: Sun, 9 Oct 2022 02:31:30 +0300 Subject: [PATCH 3/3] add clan in table --- src/admin/addAdminMarketCard/addAdminMarket.css | 2 +- src/admin/adminMarket/adminMarket.css | 2 +- src/admin/adminMarketPopUp/adminMarketPopUp.css | 2 +- src/admin/adminUserCard/adminUserCard.css | 2 +- src/admin/userTable/index.tsx | 3 ++- src/admin/userTable/userTable.css | 2 +- src/app/interfaces.ts | 1 + 7 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/admin/addAdminMarketCard/addAdminMarket.css b/src/admin/addAdminMarketCard/addAdminMarket.css index 8b2c69b..7ea6872 100644 --- a/src/admin/addAdminMarketCard/addAdminMarket.css +++ b/src/admin/addAdminMarketCard/addAdminMarket.css @@ -1,7 +1,7 @@ .addProduct{ padding-top: 200px; width: 100%; - height: 100vh; + min-height: 100vh; background: linear-gradient(85.91deg, #096DD9 0%, #40A9FF 100%); display: flex; flex-direction: column; diff --git a/src/admin/adminMarket/adminMarket.css b/src/admin/adminMarket/adminMarket.css index c77cb92..68a6526 100644 --- a/src/admin/adminMarket/adminMarket.css +++ b/src/admin/adminMarket/adminMarket.css @@ -19,7 +19,7 @@ .market{ padding-top: 200px; width: 100%; - height: 100vh; + min-height: 100vh; background: linear-gradient(85.91deg, #096DD9 0%, #40A9FF 100%); display: flex; flex-direction: column; diff --git a/src/admin/adminMarketPopUp/adminMarketPopUp.css b/src/admin/adminMarketPopUp/adminMarketPopUp.css index 8ab03ed..564fea1 100644 --- a/src/admin/adminMarketPopUp/adminMarketPopUp.css +++ b/src/admin/adminMarketPopUp/adminMarketPopUp.css @@ -1,7 +1,7 @@ .changeProduct{ padding-top: 200px; width: 100%; - height: 100vh; + min-height: 100vh; background: linear-gradient(85.91deg, #096DD9 0%, #40A9FF 100%); display: flex; flex-direction: column; diff --git a/src/admin/adminUserCard/adminUserCard.css b/src/admin/adminUserCard/adminUserCard.css index 5a14102..00621bf 100644 --- a/src/admin/adminUserCard/adminUserCard.css +++ b/src/admin/adminUserCard/adminUserCard.css @@ -1,7 +1,7 @@ .userCard{ padding-top: 200px; width: 100%; - height: 100vh; + min-height: 100vh; background: linear-gradient(85.91deg, #096DD9 0%, #40A9FF 100%); display: flex; flex-direction: column; diff --git a/src/admin/userTable/index.tsx b/src/admin/userTable/index.tsx index f7dbfd6..a9921d1 100644 --- a/src/admin/userTable/index.tsx +++ b/src/admin/userTable/index.tsx @@ -142,6 +142,7 @@ export const UserTable:React.FC = () =>{ respect: user.respect, balance: user.salary, jobTittle: user.department, + clan: user.clan_name }) as EmployerIE )))) }) adminFetcher.get("season/clans/").then((response:any)=>{ @@ -168,7 +169,7 @@ export const UserTable:React.FC = () =>{ { name: user.name, balance: user.balance, - command: user.command, + command: user.clan, speciality: user.jobTittle, key: user.telegramID, telegram: user.telegramID, diff --git a/src/admin/userTable/userTable.css b/src/admin/userTable/userTable.css index 5c1bc49..a2e6885 100644 --- a/src/admin/userTable/userTable.css +++ b/src/admin/userTable/userTable.css @@ -1,7 +1,7 @@ .userTable{ padding-top: 200px; width: 100%; - height: 100vh; + min-height: 100vh; background: linear-gradient(85.91deg, #096DD9 0%, #40A9FF 100%); display: flex; flex-direction: column; diff --git a/src/app/interfaces.ts b/src/app/interfaces.ts index a9aafeb..3a9b021 100644 --- a/src/app/interfaces.ts +++ b/src/app/interfaces.ts @@ -26,6 +26,7 @@ export interface EmployerIE extends UserIE{ respect: number, telegramID: string, command: string, + clan:string }