diff --git a/public/mock.png b/public/mock.png new file mode 100644 index 0000000..49cde8c Binary files /dev/null and b/public/mock.png differ diff --git a/src/Transaction.tsx b/src/Transaction.tsx new file mode 100644 index 0000000..276ef2c --- /dev/null +++ b/src/Transaction.tsx @@ -0,0 +1,44 @@ +import { Button, Input } from "antd"; +import React, { useState } from "react"; +import { adminFetcher, hrFetcher } from "./app/hooks"; + +export const Transaction:React.FC = () =>{ + const [user, setUser] = useState("") + const [amount, setAmount] = useState(0) + + const reset = () =>{ + setUser("") + setAmount(0) + } + + const sendCoins = () =>{ + let formData = new FormData() + formData.append("amount", amount.toString()) + formData.append("username", user) + + hrFetcher.post("blockchain/transact/", formData).then(e=>{ + alert("Коины переведены!") + reset() + } + + ) + } + return( +
+
+
Перевод/Выдача DigitalRubles
+
+
+
Telegram username
+ setUser(e.target.value)} placeholder="firesieht"> +
+
+
Сумма в коинах
+ setAmount(Number(e.target.value))} placeholder="100"> +
+
+ +
+
+ ); +} \ No newline at end of file diff --git a/src/admin/addAdminMarketCard/addAdminMarket.css b/src/admin/addAdminMarketCard/addAdminMarket.css index 7ea6872..9ef2a3a 100644 --- a/src/admin/addAdminMarketCard/addAdminMarket.css +++ b/src/admin/addAdminMarketCard/addAdminMarket.css @@ -6,6 +6,7 @@ display: flex; flex-direction: column; align-items: center; + gap:30px } .addProductCard{ @@ -109,4 +110,29 @@ align-items: center; justify-content: center; gap:25px -} \ No newline at end of file +} + +.userPreview{ + background: #262626; + border-radius: 16px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 32px 64px; + gap: 36px; + width: 75%; + font-family: 'Roboto', sans-serif; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 22px; + /* identical to box height, or 157% */ + + text-align: right; + + /* Character/Title .85 */ + + color:#fff; +} + diff --git a/src/admin/addAdminMarketCard/index.tsx b/src/admin/addAdminMarketCard/index.tsx index 37eb928..d9a8130 100644 --- a/src/admin/addAdminMarketCard/index.tsx +++ b/src/admin/addAdminMarketCard/index.tsx @@ -47,6 +47,10 @@ export const AddAdminMarketProduct:React.FC = () =>{ link:"/admin/market/add", name:"Cоздать товар (NFT)" }, + { + link:"/admin/transaction", + name:"История транзакций" + }, ]} name={user.name}>
diff --git a/src/admin/adminMarket/index.tsx b/src/admin/adminMarket/index.tsx index c420c54..389059c 100644 --- a/src/admin/adminMarket/index.tsx +++ b/src/admin/adminMarket/index.tsx @@ -60,6 +60,10 @@ export const AdminMarket:React.FC = () =>{ link:"/admin/market/add", name:"Cоздать товар (NFT)" }, + { + link:"/admin/transaction", + name:"История транзакций" + }, ]} name={user.name}>
diff --git a/src/admin/adminMarketPopUp/index.tsx b/src/admin/adminMarketPopUp/index.tsx index bb8aaed..90b6798 100644 --- a/src/admin/adminMarketPopUp/index.tsx +++ b/src/admin/adminMarketPopUp/index.tsx @@ -43,7 +43,11 @@ export const AdminMarketPopUp:React.FC = () =>{ { link:"/admin/users", name:"Участники" - } + }, + { + link:"/admin/transaction", + name:"История транзакций" + }, ]} name={user.name}>
diff --git a/src/admin/adminTransactions/index.tsx b/src/admin/adminTransactions/index.tsx new file mode 100644 index 0000000..15ec420 --- /dev/null +++ b/src/admin/adminTransactions/index.tsx @@ -0,0 +1,7 @@ +import React from "react"; + +export const AdminTransactions:React.FC = () =>{ + return(
+ +
); +} \ No newline at end of file diff --git a/src/admin/userTable/index.tsx b/src/admin/userTable/index.tsx index a9921d1..22e06c3 100644 --- a/src/admin/userTable/index.tsx +++ b/src/admin/userTable/index.tsx @@ -140,7 +140,7 @@ export const UserTable:React.FC = () =>{ command: user.command, role: user.type, respect: user.respect, - balance: user.salary, + balance: user.money, jobTittle: user.department, clan: user.clan_name }) as EmployerIE )))) @@ -156,7 +156,7 @@ export const UserTable:React.FC = () =>{ command: user.command, role: user.type, respect: user.respect, - balance: user.salary, + balance: user.money, jobTittle: user.department, }) )) } as ClanIE)) @@ -202,7 +202,11 @@ export const UserTable:React.FC = () =>{ link:"/admin/market/add", name:"Cоздать товар (NFT)" }, - + { + link:"/admin/transaction", + name:"История транзакций" + }, + ]} name={user.name}>
diff --git a/src/app/admin/adminSlice.ts b/src/app/admin/adminSlice.ts index fd5904d..e3bcc13 100644 --- a/src/app/admin/adminSlice.ts +++ b/src/app/admin/adminSlice.ts @@ -3,8 +3,6 @@ import { stat } from 'fs' 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' @@ -15,7 +13,7 @@ const initState = { wallet:"123214", balance: 100, id:"1", - role:Roles.admin, + role:"ADMIN", name:"Firesieht" } as UserIE, //потом достается запросом market: { diff --git a/src/app/consts.ts b/src/app/consts.ts index 2538250..83b8b4f 100644 --- a/src/app/consts.ts +++ b/src/app/consts.ts @@ -1,2 +1,4 @@ export const host = "https://dev.akarpov.ru/api/" -export const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjY1ODI0ODQxLCJpYXQiOjE2NjUyMjQ4NDEsImp0aSI6ImIyMjgzZjg0MmQ0NjQ4ZDU5MGY3N2Y1NzU2NDU3YjUyIiwidXNlcl9pZCI6NH0.-jAQjFLV9WCZEbthdpO-JDbRaL3N3eTCNr9Vo-PAUEk" \ No newline at end of file +export const adminToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjY1ODcyMzQwLCJpYXQiOjE2NjUyNzIzNDAsImp0aSI6IjZkNGUxOTQ0ZTE3ZjQ4OTk4MjllYmU4Mzk2NDMwZTVlIiwidXNlcl9pZCI6Nn0.ivyEB13zMGS4liCn2N2fHUi0q9bbI8iaRWBXdiO30d4" +export const hrToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjY1ODcyMzYxLCJpYXQiOjE2NjUyNzIzNjEsImp0aSI6Ijc3ZDk1ZTI2NWJkNzQ4NGRhNWY1MjYyNDE4YWQ2NzAwIiwidXNlcl9pZCI6NX0.luP2N8g_Yp3TNEwIBMYhSTSdSpUj3-QzT4PGfoYnM0k" +export const workerToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjY1ODcyMzkxLCJpYXQiOjE2NjUyNzIzOTEsImp0aSI6IjBlYzQxOTUzMTA2NDRlOWFiNzE2NTgyZWJmZDY0MTBmIiwidXNlcl9pZCI6NH0.GULKUG-2iuEAVSPXdREC0wPbQbSsSaTLqQ3ZJblwtAk" \ No newline at end of file diff --git a/src/app/hooks.ts b/src/app/hooks.ts index 4ea28b1..2592a21 100644 --- a/src/app/hooks.ts +++ b/src/app/hooks.ts @@ -1,17 +1,38 @@ import axios from 'axios'; import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; import type { RootAdminState, AppAdminDispatch } from './adminStore'; -import { host, token } from './consts'; +import { host, adminToken, hrToken, workerToken } from './consts'; +import { AppHRDispatch, RootHRState } from './hrStore'; // Use throughout your app instead of plain `useDispatch` and `useSelector` export const useAppDispatch = () => useDispatch(); +export const useHRDispatch = () => useDispatch(); export const useAppSelector: TypedUseSelectorHook = useSelector; +export const useHRSelector: TypedUseSelectorHook = useSelector; export const adminFetcher = axios.create( { baseURL: host, timeout: 5000, headers: { - Authorization: 'Bearer ' + token + Authorization: 'Bearer ' + adminToken + } + } +) +export const hrFetcher = axios.create( + { + baseURL: host, + timeout: 5000, + headers: { + Authorization: 'Bearer ' + hrToken + } + } +) +export const workerFetcher = axios.create( + { + baseURL: host, + timeout: 5000, + headers: { + Authorization: 'Bearer ' + workerToken } } ) \ No newline at end of file diff --git a/src/app/hr/hrSlice.ts b/src/app/hr/hrSlice.ts new file mode 100644 index 0000000..193a678 --- /dev/null +++ b/src/app/hr/hrSlice.ts @@ -0,0 +1,158 @@ +import { createAsyncThunk, createSlice, createSelector, PayloadAction } from '@reduxjs/toolkit' +import { EventAttendence, EventIE, HRIE} from '../interfaces' +import { AppHRDispatch, RootHRState } from '../hrStore' +import { hrFetcher, useAppDispatch } from '../hooks' + + +const initState = { + me: {} as HRIE, + events: [] as EventIE[], + currentEvent: "", + attendences: [] as EventAttendence[], +} + +const hrSlice = createSlice( + { + name: "hrSlice", + initialState: initState, + reducers:{ + setMe(state, action:PayloadAction){ + state.me = action.payload + }, + setEvents(state, action:PayloadAction){ + state.events = action.payload + }, + setAttendences(state, action:PayloadAction){ + state.attendences = action.payload + }, + setCurrentEvent(state, aaction:PayloadAction){ + state.currentEvent = aaction.payload + }, + addEvent(state, action:PayloadAction){ + state.events = state.events.concat([action.payload]) + }, + delEvent(state, action:PayloadAction){ + let events = state.events + let ind = 0 + + events.forEach((event:EventIE, index:number) => { + if(event.slug == action.payload){ + ind = index + } + }); + events.splice(ind, 1) + state.events = events + }, + updateEvent(state, action:PayloadAction){ + let events = state.events + events.forEach((event:EventIE, index:number) => { + if(event.slug == action.payload.slug){ + events[index] = action.payload + } + }); + state.events = events + }, + submitAttendance(state, action:PayloadAction){ + let attendences = state.attendences + + attendences.forEach((attendance:EventAttendence, index:number) => { + if(attendance.worker_username == action.payload){ + attendences[index].attended = true + } + }); + state.attendences = attendences + } + + } + } +) + + + + +export async function fetchAddEvent(dispatch:AppHRDispatch, params:{name: string, about: string, starts:string, image:File}) { + //тут идет фетч + const formData = new FormData() + + formData.append("name",params.name) + formData.append("about",params.about) + formData.append("image", params.image) + formData.append("starts",params.starts) + + hrFetcher.post("events/", formData).then((response)=>{ + dispatch( + addEvent( + { + name: response.data.name, + about: response.data.about, + slug: response.data.slug, + creator: { + wallet: "", + role: response.data.creator.type, + telegram: response.data.creator.telegram, + command: response.data.creator.command, + respect: response.data.creator.respect, + balance: response.data.creator.money, + name: response.data.creator.name + } as HRIE, + starts: response.data.starts, + image: response.data.image, + planning: Number(response.data.planning), + attended: Number(response.data.attended) + } as EventIE + ) + ) + + }) +} + +export async function fetchDelEvent(dispatch:AppHRDispatch, params:string) { + + hrFetcher.delete("events/" + params).then(()=>{ + dispatch(delEvent(params)) + }) +} + +export async function fetchSubmitAttendance(dispatch:AppHRDispatch, user:string, currentEvent:string){ + const formData = new FormData() + formData.append("username", user) + + hrFetcher.post("events/attendance/" + currentEvent + "/submit/", formData).then(response=>{ + dispatch(submitAttendance(user)) + }) + + const salaryData = new FormData() + salaryData.append("username", user) + salaryData.append("amount", "1") + hrFetcher.post("blockchain/transact/", salaryData) +} + + +export const getCurrentEvent = createSelector( + (state:RootHRState) => state.hrSlice.events.filter(el=> el.slug == state.hrSlice.currentEvent)[0], + (field)=>field +) +export const getEvents = createSelector( + (state:RootHRState) => state.hrSlice.events, + (field)=>field +) +export const getMe = createSelector( + (state:RootHRState) => state.hrSlice.me, + (field)=>field +) + + + + +export const { + setEvents, + setAttendences, + setCurrentEvent, + addEvent, + delEvent, + updateEvent, + submitAttendance, + setMe +} = hrSlice.actions + +export default hrSlice.reducer \ No newline at end of file diff --git a/src/app/hrStore.ts b/src/app/hrStore.ts new file mode 100644 index 0000000..661541b --- /dev/null +++ b/src/app/hrStore.ts @@ -0,0 +1,16 @@ +import { configureStore, ThunkAction, Action } from '@reduxjs/toolkit'; +import hrSlice from './hr/hrSlice'; +export const hrStore = configureStore({ + reducer: { + hrSlice: hrSlice, + }, +}); + +export type AppHRDispatch = typeof hrStore.dispatch; +export type RootHRState = ReturnType; +export type AppHRThunk = ThunkAction< + ReturnType, + RootHRState, + unknown, + Action +>; diff --git a/src/app/interfaces.ts b/src/app/interfaces.ts index 3a9b021..7e71a7f 100644 --- a/src/app/interfaces.ts +++ b/src/app/interfaces.ts @@ -14,7 +14,7 @@ export enum Specialities{ export interface UserIE{ wallet:string, - role:Roles + role:string balance: number, name:string, } @@ -26,17 +26,32 @@ export interface EmployerIE extends UserIE{ respect: number, telegramID: string, command: string, - clan:string + clan:string, + money:number, } +export interface HRIE extends UserIE{ + respect:number, + command:number, + telegram: string, +} export interface EventIE{ name:string, - description: string, - date: Date, - time:Date, - org: number; - visitors: number[] + about: string, + starts: string, + slug:string, + creator:HRIE, + image:string, + planning:number, + attended:number +} + +export interface EventAttendence{ + id:number, + event_slug:string, + worker_username:string, + attended:boolean } export interface ProductIE{ diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index 601deb5..471127f 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -1,8 +1,6 @@ import "./Header.css" import React from "react" import { Link, useLocation, useParams } from "react-router-dom" -import axios, { AxiosHeaders } from 'axios'; -import { host, token } from "../../app/consts"; interface HeaderIE{ links: { diff --git a/src/components/userPreview/index.tsx b/src/components/userPreview/index.tsx index bfc3129..27d3c83 100644 --- a/src/components/userPreview/index.tsx +++ b/src/components/userPreview/index.tsx @@ -1,6 +1,6 @@ import { Tag } from 'antd' import react from 'react' - +import "./style.css" interface IUserPreview{ level: number; diff --git a/src/hr/EventCard/eventCard.css b/src/hr/EventCard/eventCard.css new file mode 100644 index 0000000..e83a526 --- /dev/null +++ b/src/hr/EventCard/eventCard.css @@ -0,0 +1,5 @@ +.eventImg{ + height: 50%; + max-height: 150px; + border-radius: 16px 16px 0px 0px; +} \ No newline at end of file diff --git a/src/hr/EventCard/index.tsx b/src/hr/EventCard/index.tsx new file mode 100644 index 0000000..fee8540 --- /dev/null +++ b/src/hr/EventCard/index.tsx @@ -0,0 +1,37 @@ +import { Button } from "antd" +import React from "react" +import { useNavigate } from "react-router-dom" +import { useHRDispatch } from "../../app/hooks" +import { fetchDelEvent } from "../../app/hr/hrSlice" +import "../../components/prevMarketCard/prevMarketCard.css" +import "./eventCard.css" + +interface EventCardIE{ + image:string, + cost: number, + descr: string, + name:string, + members: number + slug?:string +} + +export const EventCard:React.FC = (props) =>{ + let dispatch = useHRDispatch() + let navigator = useNavigate() + + return( +
+ +
+
+ +
{props.cost}
+
+
{props.name}
+
{props.descr.split(" ").slice(0,6).join(" ")}
+ + +
+
+ ) +} \ No newline at end of file diff --git a/src/hr/addEvent/addEvent.css b/src/hr/addEvent/addEvent.css new file mode 100644 index 0000000..e69de29 diff --git a/src/hr/addEvent/index.tsx b/src/hr/addEvent/index.tsx new file mode 100644 index 0000000..1013f41 --- /dev/null +++ b/src/hr/addEvent/index.tsx @@ -0,0 +1,91 @@ +import "./addEvent.css" +import { Button, DatePicker, Input } from "antd"; +import React, { useState } from "react" +import { useNavigate } from "react-router-dom"; +import { useHRDispatch } from "../../app/hooks"; +import { fetchAddEvent } from "../../app/hr/hrSlice"; +import { FileUploader } from "../../components/fileUploader"; +import { Header } from "../../components/Header"; +import { EventCard } from "../EventCard"; + + +export const AddEvent: React.FC = () =>{ + + const [name, setName] = useState("") + const [about, setAbout] = useState("") + const [starts, setStarts] = useState("") + const [image, setImage] = useState() + + let navigate = useNavigate() + let dispatch = useHRDispatch() + + + + const create = () =>{ + fetchAddEvent(dispatch, { + name:name, + about:about, + starts:starts, + image:image as any + }) + + alert("Ивент успешно создан!") + + navigate("/hr") + + } + + return( +
+
+
+
Cоздать новое событие
+
+ +
+
+
Название
+ setName(e.target.value)}> +
+
+
Описание
+ setAbout(e.target.value)}> +
+
+
Дата проведения
+ setStarts(datestring)} /> +
+
+
Картинка
+ setImage(file)}> +
+
+
+
+ + +
+
+
+ ); +} \ No newline at end of file diff --git a/src/hr/index.tsx b/src/hr/index.tsx new file mode 100644 index 0000000..2f835c9 --- /dev/null +++ b/src/hr/index.tsx @@ -0,0 +1,100 @@ +import { Tag } from "antd"; +import React from "react"; +import { hrFetcher, useAppSelector, useHRDispatch, useHRSelector } from "../app/hooks"; +import { getEvents, getMe, setEvents, setMe } from "../app/hr/hrSlice"; +import { RootHRState } from "../app/hrStore"; +import { EventIE, HRIE } from "../app/interfaces"; +import { Header } from "../components/Header"; +import { UserPreview } from "../components/userPreview"; +import { EventCard } from "./EventCard"; + + +export const HR:React.FC = () =>{ + let me = useHRSelector((state:RootHRState)=>getMe(state)) + let dispatch = useHRDispatch() + let events = useHRSelector((state:RootHRState)=>getEvents(state)) + + + if (me.telegram == undefined){ + hrFetcher.get("users/self/").then(response=>{ + dispatch(setMe({ + wallet: response.data.wallet_public_key, + role: response.data.type, + telegram: response.data.telegram, + command: response.data.command, + respect: response.data.respect, + balance: response.data.money, + name: response.data.name + } as HRIE)) + }) + hrFetcher.get("events/").then(resp=>{ + dispatch(setEvents(resp.data.map((response:any)=>({ + name: response.name, + about: response.about, + slug: response.slug, + creator: { + wallet: "", + role: response.creator.type, + telegram: response.creator.telegram, + command: response.creator.command, + respect: response.creator.respect, + balance: response.creator.money, + name: response.creator.name + } as HRIE, + starts: response.starts, + image: response.image, + planning: Number(response.planning), + attended: Number(response.attended) + } as EventIE)))) + }) + } + + return( +
+
+
+ HR]} + description={"Sample"} + score={Number(me.respect).toString()} + > +
+
+
Доступные события
+
+ { + events.map(event=>) + } +
+
+
+ ) +} \ No newline at end of file diff --git a/src/hr/regUsers/index.tsx b/src/hr/regUsers/index.tsx new file mode 100644 index 0000000..82b540e --- /dev/null +++ b/src/hr/regUsers/index.tsx @@ -0,0 +1,94 @@ +import React, { useState } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import "./regUsers.css" +import type { ColumnsType } from 'antd/es/table'; +import { Button, Space, Table, Tag } from 'antd'; +import { fetchSubmitAttendance, getCurrentEvent, setCurrentEvent } from "../../app/hr/hrSlice"; +import { hrFetcher, useHRDispatch, useHRSelector } from "../../app/hooks"; +import { RootHRState } from "../../app/hrStore"; + +interface DataTypeIE{ + key:string, + id:number, + telegram:string, + attended: boolean +} + + +export const RegUsers:React.FC = () =>{ + const [attendance, setAttendance] = useState([-1 as any]) + let {name} = useParams() + + let navigator = useNavigate() + const collator = new Intl.Collator('ru'); + const data:DataTypeIE[] = [] + let dispatch = useHRDispatch() + + dispatch(setCurrentEvent(name as string)) + if (attendance[0] == -1){ + hrFetcher.get("events/attendance/"+name+"/list/").then(response=>setAttendance(response.data)) + + } + + + + const columns: ColumnsType = [ + { + title: 'ID', + dataIndex: 'id', + key: 'id', + defaultSortOrder: 'descend', + sorter: (a, b) => a.id - b.id , + }, + { + title: 'Telegram', + dataIndex: 'telegram', + key: 'telegram', + sorter: (a, b) => collator.compare(a.telegram, b.telegram) , + + }, + + { + title: 'Респект', + dataIndex: 'telegram', + key: 'telegram', + render: text=>
{ "5"}
+ }, + { + title: 'Начислено', + dataIndex: 'attended', + key: 'attended', + render: text=> + {text? "Да":"Нет"} + + }, + { + title: "Награда", + dataIndex: 'speciality', + key: 'speciality', + render: (_, recorder) => + } + ] + + attendance.forEach((attend)=>{ + data.push({ + key:attend.id, + id: attend.id, + telegram: attend.worker_username, + attended: attend.attended + } as DataTypeIE) + }) + + let currentEvent = useHRSelector((state:RootHRState)=>getCurrentEvent(state)) + + + return( +
+
+
Участники мероприятия {currentEvent.name}
+ + + + + ); +} \ No newline at end of file diff --git a/src/hr/regUsers/regUsers.css b/src/hr/regUsers/regUsers.css new file mode 100644 index 0000000..e69de29 diff --git a/src/hr/transactionHistory/index.tsx b/src/hr/transactionHistory/index.tsx new file mode 100644 index 0000000..e95a9f0 --- /dev/null +++ b/src/hr/transactionHistory/index.tsx @@ -0,0 +1,126 @@ +import { Button, Table, Tag } from "antd"; +import { ColumnsType } from "antd/es/table"; +import React, { useState } from "react"; +import { useLocation, useNavigate } from "react-router-dom"; +import { adminFetcher, hrFetcher, useHRDispatch } from "../../app/hooks"; +import { Header } from "../../components/Header"; + +interface DataTypeIE{ + key:string, + type:string, + user_from:string, + user_to: string, + amount: number +} + +export const TransactionHistory: React.FC = () =>{ + const [transaction, setTransaction] = useState([-1] as any) + let location = useLocation() + let hr; + if (location.pathname.split("/")[1] == "hr"){ + hr = true + } + + if (transaction[0] == -1){ + if(hr){ + console.log(1) + hrFetcher.get("blockchain/history/").then(response=>setTransaction(response.data)) + } + else{ + console.log(2) + adminFetcher.get("blockchain/history/").then(response=>setTransaction(response.data)) + + } + } + let navigator = useNavigate() + const collator = new Intl.Collator('ru'); + const data:DataTypeIE[] = [] + + const columns: ColumnsType = [ + { + title: 'Тип операции', + dataIndex: 'type', + key: 'type', + sorter: (a, b) => collator.compare(a.type, b.type), + render: text=> + {text} + + }, + { + title: 'Отправитель', + dataIndex: 'user_from', + key: 'user_from', + sorter: (a, b) => collator.compare(a.user_from, b.user_from) , + + }, + { + title: 'Получатель', + dataIndex: 'user_to', + key: 'user_to', + sorter: (a, b) => collator.compare(a.user_to, b.user_to) , + + }, + { + title: 'Сумма', + dataIndex: 'amount', + key: 'amount', + render: text=>
{ text}
+ }, + ] + transaction.forEach((el:any)=>{ + data.push({ + key: el.type, + type: el.type, + user_from: el.user_from, + user_to: el.user_to, + amount: el.amount, + } as DataTypeIE) + }) + + return( +
+ {hr?
:
+ } + + +
+
История транзакций
+ +
+ + + + ); +} \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index 8b3d39d..9535ef1 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -23,6 +23,12 @@ import { AdminClans } from './admin/adminClans'; import { AddUser } from './admin/addUser'; import { UserLk } from './user/lk'; import { Clan } from './user/clan'; +import { HR } from './hr'; +import { hrStore } from './app/hrStore'; +import { AddEvent } from './hr/addEvent'; +import { RegUsers } from './hr/regUsers'; +import { TransactionHistory } from './hr/transactionHistory'; +import { Transaction } from './Transaction'; import { ClanWar } from './user/clanWar'; import { Leaderboard } from './user/leaderboard'; import { Marketplace } from './user/marketplace'; @@ -42,7 +48,16 @@ const router = createBrowserRouter( }>}>}> + }> +
}>
+ }> + }> + }> + } /> + } /> + + }> } /> } />