mirror of
https://github.com/emo2007/block-accounting.git
synced 2025-01-18 23:46:27 +00:00
back integ
Co-authored-by: Nick <emochka2007@users.noreply.github.com>
This commit is contained in:
parent
8791e4f103
commit
f01dbe094b
107
front/package-lock.json
generated
107
front/package-lock.json
generated
@ -10,11 +10,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^5.3.7",
|
"@ant-design/icons": "^5.3.7",
|
||||||
"antd": "^5.17.0",
|
"antd": "^5.17.0",
|
||||||
|
"axios": "^1.7.2",
|
||||||
|
"js-cookie": "^3.0.5",
|
||||||
"next": "14.2.3",
|
"next": "14.2.3",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18"
|
"react-dom": "^18"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/js-cookie": "^3.0.6",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
@ -649,6 +652,12 @@
|
|||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/js-cookie": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/json5": {
|
"node_modules/@types/json5": {
|
||||||
"version": "0.0.29",
|
"version": "0.0.29",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||||
@ -1165,6 +1174,11 @@
|
|||||||
"integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
|
"integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
|
},
|
||||||
"node_modules/available-typed-arrays": {
|
"node_modules/available-typed-arrays": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
||||||
@ -1189,6 +1203,16 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/axios": {
|
||||||
|
"version": "1.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
|
||||||
|
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.15.6",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
|
"proxy-from-env": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/axobject-query": {
|
"node_modules/axobject-query": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
|
||||||
@ -1385,6 +1409,17 @@
|
|||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/combined-stream": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"dependencies": {
|
||||||
|
"delayed-stream": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/commander": {
|
"node_modules/commander": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
||||||
@ -1563,6 +1598,14 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dequal": {
|
"node_modules/dequal": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||||
@ -2330,6 +2373,25 @@
|
|||||||
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
|
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/follow-redirects": {
|
||||||
|
"version": "1.15.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||||
|
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"debug": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/for-each": {
|
"node_modules/for-each": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
||||||
@ -2355,6 +2417,19 @@
|
|||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/form-data": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||||
|
"dependencies": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fs.realpath": {
|
"node_modules/fs.realpath": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
@ -3155,6 +3230,14 @@
|
|||||||
"jiti": "bin/jiti.js"
|
"jiti": "bin/jiti.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/js-cookie": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
@ -3343,6 +3426,25 @@
|
|||||||
"node": ">=8.6"
|
"node": ">=8.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.52.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "2.1.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "1.52.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/minimatch": {
|
"node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
@ -3971,6 +4073,11 @@
|
|||||||
"react-is": "^16.13.1"
|
"react-is": "^16.13.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/proxy-from-env": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||||
|
},
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||||
|
@ -11,11 +11,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^5.3.7",
|
"@ant-design/icons": "^5.3.7",
|
||||||
"antd": "^5.17.0",
|
"antd": "^5.17.0",
|
||||||
|
"axios": "^1.7.2",
|
||||||
|
"js-cookie": "^3.0.5",
|
||||||
"next": "14.2.3",
|
"next": "14.2.3",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18"
|
"react-dom": "^18"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/js-cookie": "^3.0.6",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
|
37
front/src/app/axios/api-types.ts
Normal file
37
front/src/app/axios/api-types.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
export type LoginResponse = {
|
||||||
|
token: string;
|
||||||
|
token_expired_at: number;
|
||||||
|
refresh_token: string;
|
||||||
|
refresh_token_expired_at: number;
|
||||||
|
};
|
||||||
|
export type Organization = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
address: string;
|
||||||
|
};
|
||||||
|
export type OrganizationsResponse = {
|
||||||
|
items: Organization[];
|
||||||
|
};
|
||||||
|
export type NewOrgResponse = {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
export type Ids = {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
export type ParticipantsResponse = {
|
||||||
|
ids: Ids[];
|
||||||
|
};
|
||||||
|
export type AddPartResponse = {
|
||||||
|
name: string;
|
||||||
|
position: string;
|
||||||
|
wallet_address: string;
|
||||||
|
};
|
||||||
|
export type PublicKey = {
|
||||||
|
public_key: string;
|
||||||
|
};
|
||||||
|
export type DeployResponse = {
|
||||||
|
title: string;
|
||||||
|
owners: PublicKey[];
|
||||||
|
confirmations: number;
|
||||||
|
};
|
||||||
|
export type MultiSigResponse = {};
|
27
front/src/app/axios/global-api.ts
Normal file
27
front/src/app/axios/global-api.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
// const tokenStorage = Cookies.get("accessToken");
|
||||||
|
|
||||||
|
export const globalService = axios.create({
|
||||||
|
baseURL: "http://209.141.36.222:8085/",
|
||||||
|
timeout: 10000,
|
||||||
|
});
|
||||||
|
|
||||||
|
globalService.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
// Get the access token from the cookie
|
||||||
|
const token = Cookies.get("accessToken");
|
||||||
|
console.log(token);
|
||||||
|
|
||||||
|
// If the token exists, set it in the Authorization header
|
||||||
|
if (token) {
|
||||||
|
config.headers.Authorization = `Bearer ${token}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
// If there's an error in the request configuration, you can handle it here
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
91
front/src/app/axios/global.service.ts
Normal file
91
front/src/app/axios/global.service.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { globalService } from "../axios/global-api";
|
||||||
|
import { AxiosResponse } from "axios";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
import {
|
||||||
|
LoginResponse,
|
||||||
|
OrganizationsResponse,
|
||||||
|
NewOrgResponse,
|
||||||
|
ParticipantsResponse,
|
||||||
|
AddPartResponse,
|
||||||
|
DeployResponse,
|
||||||
|
MultiSigResponse,
|
||||||
|
} from "./api-types";
|
||||||
|
export class AccountingService {
|
||||||
|
async login(seedKey: string): Promise<AxiosResponse<LoginResponse>> {
|
||||||
|
console.log(seedKey);
|
||||||
|
|
||||||
|
return await globalService.post("login", {
|
||||||
|
mnemonic: seedKey,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async register(seedKey: string) {
|
||||||
|
return await globalService.post("join", {
|
||||||
|
mnemonic: seedKey,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async newOrganization(
|
||||||
|
name: string,
|
||||||
|
address: string
|
||||||
|
): Promise<AxiosResponse<NewOrgResponse>> {
|
||||||
|
return await globalService.post("organizations", {
|
||||||
|
name,
|
||||||
|
address,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getOrganizations(): Promise<AxiosResponse<OrganizationsResponse>> {
|
||||||
|
return await globalService.post("organizations/fetch", {
|
||||||
|
data: {
|
||||||
|
limit: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getEmployees(
|
||||||
|
organizationId: string
|
||||||
|
): Promise<AxiosResponse<ParticipantsResponse>> {
|
||||||
|
return await globalService.get(
|
||||||
|
`organizations/${organizationId}/participants`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async addEmployee(
|
||||||
|
name: string,
|
||||||
|
position: string,
|
||||||
|
wallet_address: string,
|
||||||
|
organizationId: string
|
||||||
|
): Promise<AxiosResponse<AddPartResponse>> {
|
||||||
|
return await globalService.post(
|
||||||
|
`organizations/${organizationId}/participants`,
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
position,
|
||||||
|
wallet_address,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST /organizations/{organization_id}/multisig
|
||||||
|
async deployMultisig(
|
||||||
|
organization_id: string,
|
||||||
|
title: string,
|
||||||
|
owners: string[],
|
||||||
|
confirmations: number
|
||||||
|
): Promise<AxiosResponse<DeployResponse>> {
|
||||||
|
return await globalService.post(`${organization_id}/multi-sig`, {
|
||||||
|
title,
|
||||||
|
owners,
|
||||||
|
confirmations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAllMultisigsByOrganizationId(
|
||||||
|
organizationId: string
|
||||||
|
): Promise<AxiosResponse<MultiSigResponse>> {
|
||||||
|
return await globalService.get(`organizations/${organizationId}/multisig`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const apiService = new AccountingService();
|
@ -1,37 +1,41 @@
|
|||||||
// 1. Страница входа (Login Page)
|
|
||||||
// Дизайн: Страница должна быть минималистичной с использованием профессиональной цветовой схемы (синие и серые тона). Должно быть поле для ввода мнемонической фразы (SEED_KEY) и кнопка для входа.
|
|
||||||
// Безопасность: Добавить элементы, подчеркивающие безопасность, например, иконку замка и текст, имитирующий шифрование.
|
|
||||||
// Валидация: Проверять формат введенного SEED_KEY на клиентской стороне перед отправкой на сервер.
|
|
||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { SeedItem } from "../seedItem/SeedItem";
|
import { SeedItem } from "../seedItem/SeedItem";
|
||||||
|
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useState, useEffect, FC } from "react";
|
import { useState, useEffect, FC } from "react";
|
||||||
import { EyeInvisibleOutlined, EyeTwoTone } from "@ant-design/icons";
|
import { EyeInvisibleOutlined, EyeTwoTone } from "@ant-design/icons";
|
||||||
|
import { apiService } from "../axios/global.service";
|
||||||
import { Input, Space, Button, List, Card, Typography } from "antd";
|
import { Input, Space, Button, List, Card, Typography } from "antd";
|
||||||
import { LockOutlined } from "@ant-design/icons";
|
import { LockOutlined } from "@ant-design/icons";
|
||||||
import useLoginHooks from "@/hooks/login";
|
import useLoginHooks from "@/hooks/login";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
export function LoginPage() {
|
export function LoginPage() {
|
||||||
const { passwordVisible, setPasswordVisible, seed, getSeed } =
|
const { passwordVisible, setPasswordVisible } = useLoginHooks();
|
||||||
useLoginHooks();
|
|
||||||
const [inp, setInp] = useState("");
|
const [inp, setInp] = useState("");
|
||||||
|
const [seed, setSeed] = useState<string>();
|
||||||
const [disabled, setDisabled] = useState(true);
|
const [disabled, setDisabled] = useState(true);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const onNextPageHandler = () => {
|
|
||||||
router.push("/organization");
|
const onNextPageHandler = async () => {};
|
||||||
};
|
// const getSeed = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
// setSeed(inp);
|
||||||
|
// };
|
||||||
|
console.log(inp);
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDisabled(!(inp.length >= 4));
|
setDisabled(!(inp.length >= 4));
|
||||||
}, [inp]);
|
}, [inp]);
|
||||||
|
|
||||||
const onSubmitHandler = () => {
|
const onSubmitHandler = async () => {
|
||||||
|
const result = await apiService.login(inp);
|
||||||
|
if (result) {
|
||||||
|
Cookies.set("accessToken", result.data.token);
|
||||||
|
router.push("/organization");
|
||||||
|
}
|
||||||
setInp("");
|
setInp("");
|
||||||
getSeed(inp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex relative overflow-hidden flex-col w-2/3 h-3/4 items-center justify-center gap-10 bg-white border-solid border rounded-md border-neutral-300 text-neutral-500">
|
<div className="flex relative overflow-hidden flex-col w-2/3 h-3/4 items-center justify-center gap-10 bg-white border-solid border rounded-md border-neutral-300 text-neutral-500">
|
||||||
<div className="w-full h-20 bg-[#1677FF] absolute top-0 flex items-center justify-center">
|
<div className="w-full h-20 bg-[#1677FF] absolute top-0 flex items-center justify-center">
|
||||||
@ -39,7 +43,9 @@ export function LoginPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col w-6/12 gap-3 items-start mt-20">
|
<div className="flex flex-col w-6/12 gap-3 items-start mt-20">
|
||||||
<div>
|
<div>
|
||||||
<Text type="secondary">Please enter 12 words always lowercase.</Text>
|
<Text type="secondary">
|
||||||
|
Please enter by spaces 12 words always lowercase.
|
||||||
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Space.Compact style={{ width: "100%" }}>
|
<Space.Compact style={{ width: "100%" }}>
|
||||||
@ -59,8 +65,9 @@ export function LoginPage() {
|
|||||||
}
|
}
|
||||||
placeholder="Enter your seed words in order"
|
placeholder="Enter your seed words in order"
|
||||||
onInput={(event: any) => setInp(event.target.value)}
|
onInput={(event: any) => setInp(event.target.value)}
|
||||||
maxLength={8}
|
//maxLength={8}
|
||||||
minLength={4}
|
minLength={4}
|
||||||
|
//onChange={getSeed}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
size="large"
|
size="large"
|
||||||
@ -72,14 +79,14 @@ export function LoginPage() {
|
|||||||
</Button>
|
</Button>
|
||||||
</Space.Compact>
|
</Space.Compact>
|
||||||
</div>
|
</div>
|
||||||
<div
|
{/* <div
|
||||||
className="flex flex-row w-[700px] gap-3 content-box flex-wrap
|
className="flex flex-row w-[700px] gap-3 content-box flex-wrap
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{seed.map((element: string, index: number) => (
|
{/* {seed.map((element: string, index: number) => (
|
||||||
<SeedItem key={index} seed={element} />
|
// <SeedItem key={index} seed={element} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div> */}
|
||||||
<Button
|
<Button
|
||||||
onClick={onNextPageHandler}
|
onClick={onNextPageHandler}
|
||||||
style={{ width: "150px" }}
|
style={{ width: "150px" }}
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
export class LoginService {
|
|
||||||
login(seedKey: string) {
|
|
||||||
return fetch(`backend`);
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,33 +4,32 @@ import React from "react";
|
|||||||
import { Card } from "antd";
|
import { Card } from "antd";
|
||||||
import { useState, useEffect, FC } from "react";
|
import { useState, useEffect, FC } from "react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
type OrgData = {
|
import Link from "next/link";
|
||||||
name: string;
|
import { Organization } from "../axios/api-types";
|
||||||
address: string;
|
|
||||||
phone: number;
|
|
||||||
};
|
|
||||||
type OrgItemProps = {
|
type OrgItemProps = {
|
||||||
element: OrgData;
|
element: Organization;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const OrganizationCard: FC<OrgItemProps> = ({ element }) => {
|
export const OrganizationCard: FC<OrgItemProps> = ({ element }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const onNextPageHandler = () => {
|
const id: any = element.id;
|
||||||
router.push("/organization/dashboard");
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card
|
<Card
|
||||||
title={element.name}
|
title={element.name}
|
||||||
type="inner"
|
type="inner"
|
||||||
extra={
|
extra={
|
||||||
<a onClick={onNextPageHandler} href="#">
|
<Link
|
||||||
|
href={{ pathname: "/organization/overview/dashboard/", query: id }}
|
||||||
|
>
|
||||||
More
|
More
|
||||||
</a>
|
</Link>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<p>{element.address}</p>
|
<p>{element.address}</p>
|
||||||
<p>{element.phone}</p>
|
<p>{element.name}</p>
|
||||||
</Card>
|
</Card>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
@ -6,35 +6,39 @@
|
|||||||
//* <h1>{seed.join("\n")}</h1> */shtuchka kak map
|
//* <h1>{seed.join("\n")}</h1> */shtuchka kak map
|
||||||
|
|
||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React, { useEffect } from "react";
|
||||||
import { Button, Modal } from "antd";
|
import { Button, Modal } from "antd";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { apiService } from "../axios/global.service";
|
||||||
import { OrgForm } from "./OrgForm";
|
import { OrgForm } from "./OrgForm";
|
||||||
import { OrganizationCard } from "./OrgCard";
|
import { OrganizationCard } from "./OrgCard";
|
||||||
import { FolderOpenTwoTone } from "@ant-design/icons";
|
import { FolderOpenTwoTone } from "@ant-design/icons";
|
||||||
|
import {
|
||||||
type OrgData = {
|
Organization,
|
||||||
name: string;
|
NewOrgResponse,
|
||||||
address: string;
|
OrganizationsResponse,
|
||||||
phone: number;
|
} from "../axios/api-types";
|
||||||
};
|
import Cookies from "js-cookie";
|
||||||
export function OrgCreatePage() {
|
export function OrgCreatePage() {
|
||||||
const [organizations, setOrganizations] = useState([
|
const [organizations, setOrganizations] = useState<Organization[]>([]);
|
||||||
{
|
|
||||||
name: "My Company",
|
|
||||||
address: "2930 Pearl St Boulder, CO 80301 United States",
|
|
||||||
phone: "+1303-245-0086",
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
const onFinish = (values: any) => {
|
name: "",
|
||||||
|
address: "",
|
||||||
|
});
|
||||||
|
const onFinish = async (values: any) => {
|
||||||
handleOk();
|
handleOk();
|
||||||
setOrganizations((prev: any[]) => [...prev, formData]);
|
setOrganizations((prev: any) => [...prev, formData]);
|
||||||
setFormData({});
|
|
||||||
|
// setFormData({});
|
||||||
|
const result = await apiService.newOrganization(
|
||||||
|
formData.name,
|
||||||
|
formData.address
|
||||||
|
);
|
||||||
|
if (result) {
|
||||||
|
loadOrganizations();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const [formData, setFormData] = useState({});
|
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setIsModalOpen(true);
|
setIsModalOpen(true);
|
||||||
};
|
};
|
||||||
@ -46,7 +50,15 @@ export function OrgCreatePage() {
|
|||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
};
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
loadOrganizations();
|
||||||
|
}, []);
|
||||||
|
const loadOrganizations = async () => {
|
||||||
|
const result: Organization[] = await apiService.getOrganizations();
|
||||||
|
if (result) {
|
||||||
|
setOrganizations(result.data.items);
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex relative overflow-hidden flex-col w-2/3 h-3/4 items-center justify-center z-30 gap-5 bg-white border-solid border rounded-md border-neutral-300 text-neutral-500">
|
<div className="flex relative overflow-hidden flex-col w-2/3 h-3/4 items-center justify-center z-30 gap-5 bg-white border-solid border rounded-md border-neutral-300 text-neutral-500">
|
@ -39,10 +39,10 @@ export function OrgForm({ setFormData }) {
|
|||||||
<Input
|
<Input
|
||||||
name="name"
|
name="name"
|
||||||
style={{ width: 350 }}
|
style={{ width: 350 }}
|
||||||
onInput={(e: any) =>
|
onInput={(element: any) =>
|
||||||
setFormData((prev: object) => ({
|
setFormData((prev: object) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[e.target.name]: e.target.value,
|
[element.target.name]: element.target.value,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -58,10 +58,10 @@ export function OrgForm({ setFormData }) {
|
|||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
name="address"
|
name="address"
|
||||||
onInput={(e: any) =>
|
onInput={(element: any) =>
|
||||||
setFormData((prev: object) => ({
|
setFormData((prev: object) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[e.target.name]: e.target.value,
|
[element.target.name]: element.target.value,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
style={{ width: 350 }}
|
style={{ width: 350 }}
|
@ -1,7 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import React from "react";
|
|
||||||
import { OrgProfile } from "./OrgProfile";
|
|
||||||
|
|
||||||
export default function Home() {
|
|
||||||
return <OrgProfile />;
|
|
||||||
}
|
|
@ -0,0 +1,69 @@
|
|||||||
|
"use client";
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { Select, Typography, Card, Divider, Button } from "antd";
|
||||||
|
import { WalletOutlined } from "@ant-design/icons";
|
||||||
|
const handleChange = (value: string) => {
|
||||||
|
console.log(`selected ${value}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { Title } = Typography;
|
||||||
|
|
||||||
|
export function AgreementPage() {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col w-full p-8 ">
|
||||||
|
<Title style={{ color: "#302d43" }}>Agreement</Title>
|
||||||
|
|
||||||
|
<Card className="w-full ">
|
||||||
|
<Divider
|
||||||
|
style={{ color: "#1677FF" }}
|
||||||
|
orientation="left"
|
||||||
|
orientationMargin="0"
|
||||||
|
>
|
||||||
|
<a href="#">Owners</a>
|
||||||
|
</Divider>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<Select
|
||||||
|
suffixIcon={<WalletOutlined />}
|
||||||
|
defaultValue={""}
|
||||||
|
style={{ width: "full" }}
|
||||||
|
allowClear
|
||||||
|
options={[{ value: "", label: "" }]}
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
suffixIcon={<WalletOutlined />}
|
||||||
|
defaultValue={""}
|
||||||
|
style={{ width: "full" }}
|
||||||
|
allowClear
|
||||||
|
options={[{ value: "", label: "" }]}
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
suffixIcon={<WalletOutlined />}
|
||||||
|
defaultValue={""}
|
||||||
|
style={{ width: "full" }}
|
||||||
|
allowClear
|
||||||
|
options={[{ value: "", label: "" }]}
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
suffixIcon={<WalletOutlined />}
|
||||||
|
defaultValue={""}
|
||||||
|
style={{ width: "full" }}
|
||||||
|
allowClear
|
||||||
|
options={[{ value: "", label: "" }]}
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
suffixIcon={<WalletOutlined />}
|
||||||
|
defaultValue={""}
|
||||||
|
style={{ width: "full" }}
|
||||||
|
allowClear
|
||||||
|
options={[{ value: "", label: "" }]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
<div className="flex w-full justify-end mt-8">
|
||||||
|
<Button size={"large"} style={{ width: 150 }} type="primary">
|
||||||
|
Confirm
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
11
front/src/app/organization/overview/agreement/page.tsx
Normal file
11
front/src/app/organization/overview/agreement/page.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
"use client";
|
||||||
|
import React from "react";
|
||||||
|
import { AgreementPage } from "./AgreementPage";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<div className="flex w-full h-screen bg-slate-50">
|
||||||
|
<AgreementPage />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,27 +1,10 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
import { Card } from "antd";
|
import { Card } from "antd";
|
||||||
import {
|
import { UserOutlined } from "@ant-design/icons";
|
||||||
AppstoreOutlined,
|
import { Button, List, Divider, Typography, Avatar, Skeleton } from "antd";
|
||||||
ContainerOutlined,
|
|
||||||
DesktopOutlined,
|
|
||||||
MailOutlined,
|
|
||||||
MenuFoldOutlined,
|
|
||||||
MenuUnfoldOutlined,
|
|
||||||
PieChartOutlined,
|
|
||||||
UserOutlined,
|
|
||||||
} from "@ant-design/icons";
|
|
||||||
import type { MenuProps } from "antd";
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Menu,
|
|
||||||
List,
|
|
||||||
Divider,
|
|
||||||
Typography,
|
|
||||||
Avatar,
|
|
||||||
Skeleton,
|
|
||||||
} from "antd";
|
|
||||||
interface DataType {
|
interface DataType {
|
||||||
gender?: string;
|
gender?: string;
|
||||||
name: {
|
name: {
|
||||||
@ -41,7 +24,6 @@ interface DataType {
|
|||||||
const count = 3;
|
const count = 3;
|
||||||
const fakeDataUrl = `https://randomuser.me/api/?results=${count}&inc=name,gender,email,nat,picture&noinfo`;
|
const fakeDataUrl = `https://randomuser.me/api/?results=${count}&inc=name,gender,email,nat,picture&noinfo`;
|
||||||
|
|
||||||
type MenuItem = Required<MenuProps>["items"][number];
|
|
||||||
const data = [
|
const data = [
|
||||||
"Ackee Blockchain is a team of auditors and white hat hackers who perform security audits and assessments for Ethereum and Solana.",
|
"Ackee Blockchain is a team of auditors and white hat hackers who perform security audits and assessments for Ethereum and Solana.",
|
||||||
"Global blockchain services company and Initial Coin Offering solutions provider",
|
"Global blockchain services company and Initial Coin Offering solutions provider",
|
||||||
@ -50,51 +32,23 @@ const data = [
|
|||||||
"Securing the DeFi ecosystem",
|
"Securing the DeFi ecosystem",
|
||||||
];
|
];
|
||||||
|
|
||||||
const items: MenuItem[] = [
|
|
||||||
{ key: "1", icon: <PieChartOutlined />, label: "Wallet Info" },
|
|
||||||
{ key: "2", icon: <DesktopOutlined />, label: "Option 2" },
|
|
||||||
{ key: "3", icon: <ContainerOutlined />, label: "Contracts" },
|
|
||||||
{
|
|
||||||
key: "sub1",
|
|
||||||
label: "Navigation One",
|
|
||||||
icon: <MailOutlined />,
|
|
||||||
// children: [
|
|
||||||
// { key: "5", label: "Option 5" },
|
|
||||||
// { key: "6", label: "Option 6" },
|
|
||||||
// ],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "sub2",
|
|
||||||
label: "Navigation Two",
|
|
||||||
icon: <AppstoreOutlined />,
|
|
||||||
children: [
|
|
||||||
{ key: "9", label: "Option 9" },
|
|
||||||
{ key: "10", label: "Option 10" },
|
|
||||||
{
|
|
||||||
key: "sub3",
|
|
||||||
label: "Submenu",
|
|
||||||
children: [
|
|
||||||
{ key: "11", label: "Option 11" },
|
|
||||||
{ key: "12", label: "Option 12" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const { Title } = Typography;
|
const { Title } = Typography;
|
||||||
|
|
||||||
export function OrgProfile() {
|
export function OrgProfile() {
|
||||||
const [collapsed, setCollapsed] = useState(true);
|
|
||||||
const [initLoading, setInitLoading] = useState(true);
|
const [initLoading, setInitLoading] = useState(true);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [dataEmployees, setData] = useState<DataType[]>([]);
|
const [dataEmployees, setData] = useState<DataType[]>([]);
|
||||||
const [list, setList] = useState<DataType[]>([]);
|
const [list, setList] = useState<DataType[]>([]);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const pathname = useSearchParams();
|
||||||
|
console.log(pathname.getAll("query"));
|
||||||
|
|
||||||
const onNextPageHandler = () => {
|
const onNextPageHandler = () => {
|
||||||
router.push("/organization/employees");
|
router.push("/organization/overview/employees");
|
||||||
};
|
};
|
||||||
const onMultisigPageHandler = () => {
|
const onMultisigPageHandler = () => {
|
||||||
router.push("/organization/multiSig");
|
router.push("/organization/overview/multiSig");
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch(fakeDataUrl)
|
fetch(fakeDataUrl)
|
||||||
@ -144,25 +98,8 @@ export function OrgProfile() {
|
|||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row w-full h-full bg-slate-50 gap-5 pb-20 px-30 p-10">
|
<div className="flex flex-row w-full h-full bg-slate-50 p-8">
|
||||||
<div className="w-24 py-2">
|
<div className="flex flex-col w-11/12 ">
|
||||||
<div>
|
|
||||||
<Menu
|
|
||||||
style={{
|
|
||||||
borderRadius: 8,
|
|
||||||
height: "228px",
|
|
||||||
border: "solid 1px #1677FF",
|
|
||||||
}}
|
|
||||||
defaultSelectedKeys={["1"]}
|
|
||||||
defaultOpenKeys={["sub1"]}
|
|
||||||
mode="inline"
|
|
||||||
theme="light"
|
|
||||||
inlineCollapsed={collapsed}
|
|
||||||
items={items}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col w-11/12 pr-10">
|
|
||||||
<Title style={{ color: "#302d43", textIndent: 15 }}>Dashboard</Title>
|
<Title style={{ color: "#302d43", textIndent: 15 }}>Dashboard</Title>
|
||||||
<Card
|
<Card
|
||||||
title="Organization Name"
|
title="Organization Name"
|
||||||
@ -188,7 +125,7 @@ export function OrgProfile() {
|
|||||||
orientation="left"
|
orientation="left"
|
||||||
orientationMargin="0"
|
orientationMargin="0"
|
||||||
>
|
>
|
||||||
Recent Activities
|
<a href="#">Contracts</a>
|
||||||
</Divider>
|
</Divider>
|
||||||
<List
|
<List
|
||||||
bordered
|
bordered
|
||||||
@ -214,7 +151,9 @@ export function OrgProfile() {
|
|||||||
orientation="left"
|
orientation="left"
|
||||||
orientationMargin="0"
|
orientationMargin="0"
|
||||||
>
|
>
|
||||||
Employee List
|
<a href="http://localhost:3000/organization/employees/employeeList">
|
||||||
|
Employee List
|
||||||
|
</a>
|
||||||
</Divider>
|
</Divider>
|
||||||
<List
|
<List
|
||||||
className="demo-loadmore-list"
|
className="demo-loadmore-list"
|
11
front/src/app/organization/overview/dashboard/page.tsx
Normal file
11
front/src/app/organization/overview/dashboard/page.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
"use client";
|
||||||
|
import React from "react";
|
||||||
|
import { OrgProfile } from "./id";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-row w-full h-screen bg-slate-50 gap-5">
|
||||||
|
<OrgProfile />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -6,10 +6,10 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Input, Button, Typography, Space } from "antd";
|
import { Input, Button, Typography, Space } from "antd";
|
||||||
import { MailOutlined, CopyOutlined } from "@ant-design/icons";
|
import { MailOutlined, CopyOutlined } from "@ant-design/icons";
|
||||||
export function EmployeePage() {
|
export function EmployeeInvitatonPage() {
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
return (
|
return (
|
||||||
<div className="flex relative overflow-hidden flex-col w-2/3 h-3/4 items-center justify-center gap-10 bg-white border-solid border rounded-md border-neutral-300 text-neutral-500">
|
<div className="flex relative overflow-hidden flex-col w-2/3 h-3/4 items-center justify-center gap-10 bg-white border-solid border rounded-md border-neutral-300 p-10 text-neutral-500">
|
||||||
<div className="w-full h-20 bg-[#1677FF] absolute top-0 flex items-center justify-center">
|
<div className="w-full h-20 bg-[#1677FF] absolute top-0 flex items-center justify-center">
|
||||||
<h1 className="text-white text-xl font-semibold">Invite</h1>
|
<h1 className="text-white text-xl font-semibold">Invite</h1>
|
||||||
</div>
|
</div>
|
@ -0,0 +1,103 @@
|
|||||||
|
"use client";
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { Button, Menu, List, Typography, Avatar, Skeleton } from "antd";
|
||||||
|
import { UserOutlined } from "@ant-design/icons";
|
||||||
|
import type { MenuProps } from "antd";
|
||||||
|
import { PayOutBtn } from "@/app/ui/PayOutBtn";
|
||||||
|
const count = 8;
|
||||||
|
const fakeDataUrl = `https://randomuser.me/api/?results=${count}&inc=name,gender,email,nat,picture&noinfo`;
|
||||||
|
interface DataType {
|
||||||
|
gender?: string;
|
||||||
|
name: {
|
||||||
|
title?: string;
|
||||||
|
first?: string;
|
||||||
|
last?: string;
|
||||||
|
};
|
||||||
|
email?: string;
|
||||||
|
picture: {
|
||||||
|
large?: string;
|
||||||
|
medium?: string;
|
||||||
|
thumbnail?: string;
|
||||||
|
};
|
||||||
|
nat?: string;
|
||||||
|
loading: boolean;
|
||||||
|
}
|
||||||
|
const { Title } = Typography;
|
||||||
|
type MenuItem = Required<MenuProps>["items"][number];
|
||||||
|
export function EmployeeList() {
|
||||||
|
const [collapsed, setCollapsed] = useState(true);
|
||||||
|
const [initLoading, setInitLoading] = useState(true);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [dataEmployees, setData] = useState<DataType[]>([]);
|
||||||
|
const [list, setList] = useState<DataType[]>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(fakeDataUrl)
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((res) => {
|
||||||
|
setInitLoading(false);
|
||||||
|
setData(res.results);
|
||||||
|
setList(res.results);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
const onLoadMore = () => {
|
||||||
|
setLoading(true);
|
||||||
|
setList(
|
||||||
|
dataEmployees.concat(
|
||||||
|
[...new Array(count)].map(() => ({
|
||||||
|
loading: true,
|
||||||
|
name: {},
|
||||||
|
picture: {},
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
fetch(fakeDataUrl)
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((res) => {
|
||||||
|
const newData = dataEmployees.concat(res.results);
|
||||||
|
setData(newData);
|
||||||
|
setList(newData);
|
||||||
|
setLoading(false);
|
||||||
|
// Resetting window's offsetTop so as to display react-virtualized demo underfloor.
|
||||||
|
// In real scene, you can using public method of react-virtualized:
|
||||||
|
// https://stackoverflow.com/questions/46700726/how-to-use-public-method-updateposition-of-react-virtualized
|
||||||
|
window.dispatchEvent(new Event("resize"));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const loadMore =
|
||||||
|
!initLoading && !loading ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 12,
|
||||||
|
height: 32,
|
||||||
|
lineHeight: "32px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button onClick={onLoadMore}>loading more</Button>
|
||||||
|
</div>
|
||||||
|
) : null;
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col w-full h-full gap-5 pb-20 px-30 p-8">
|
||||||
|
<Title style={{ color: "#302d43", textIndent: 15 }}>Employee List</Title>
|
||||||
|
<List
|
||||||
|
className="demo-loadmore-list"
|
||||||
|
loading={initLoading}
|
||||||
|
itemLayout="horizontal"
|
||||||
|
loadMore={loadMore}
|
||||||
|
dataSource={list}
|
||||||
|
renderItem={(item) => (
|
||||||
|
<List.Item actions={[<PayOutBtn />]}>
|
||||||
|
<Skeleton avatar title={false} loading={item.loading} active>
|
||||||
|
<List.Item.Meta
|
||||||
|
avatar={<Avatar icon={<UserOutlined />} />}
|
||||||
|
title={<a href="https://ant.design">{item.name?.last}</a>}
|
||||||
|
description="1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71"
|
||||||
|
/>
|
||||||
|
<div>wallet address</div>
|
||||||
|
</Skeleton>
|
||||||
|
</List.Item>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
"use client";
|
||||||
|
import React from "react";
|
||||||
|
import { EmployeeList } from "./EmployeeList";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<div className="flex w-full h-screen items-center justify-center bg-slate-50">
|
||||||
|
<EmployeeList />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { EmployeePage } from "./Employee";
|
import { EmployeeInvitatonPage } from "./Employee";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full h-screen items-center justify-center bg-white">
|
<div className="flex w-full h-screen items-center justify-center bg-white">
|
||||||
<EmployeePage />
|
<EmployeeInvitatonPage />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
117
front/src/app/organization/overview/layout.tsx
Normal file
117
front/src/app/organization/overview/layout.tsx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
"use client";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { BackBtn } from "@/app/ui/BackBtn";
|
||||||
|
import {
|
||||||
|
PieChartOutlined,
|
||||||
|
KeyOutlined,
|
||||||
|
UsergroupAddOutlined,
|
||||||
|
FileProtectOutlined,
|
||||||
|
WalletOutlined,
|
||||||
|
} from "@ant-design/icons";
|
||||||
|
import type { MenuProps } from "antd";
|
||||||
|
import { Menu } from "antd";
|
||||||
|
|
||||||
|
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||||
|
type MenuItem = Required<MenuProps>["items"][number];
|
||||||
|
const [collapsed, setCollapsed] = useState(true);
|
||||||
|
const items: MenuItem[] = [
|
||||||
|
{
|
||||||
|
key: "1",
|
||||||
|
icon: <PieChartOutlined />,
|
||||||
|
label: (
|
||||||
|
<Link href="http://localhost:3000/organization/overview/dashboard">
|
||||||
|
Overview
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "2",
|
||||||
|
icon: <FileProtectOutlined />,
|
||||||
|
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
key: "5",
|
||||||
|
label: (
|
||||||
|
<Link href="http://localhost:3000/organization/overview/license">
|
||||||
|
Licenses
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "6",
|
||||||
|
label: (
|
||||||
|
<Link href="http://localhost:3000/organization/overview/agreement">
|
||||||
|
Agreement
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "3",
|
||||||
|
icon: <WalletOutlined />,
|
||||||
|
label: "Transactions",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
key: "5",
|
||||||
|
label: (
|
||||||
|
<Link href="http://localhost:3000/organization/overview/pending">
|
||||||
|
Pending Contracts
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{ key: "6", label: "Option 6" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "4",
|
||||||
|
icon: <UsergroupAddOutlined />,
|
||||||
|
label: (
|
||||||
|
<Link href="http://localhost:3000/organization//overview/employees/employeeList">
|
||||||
|
Employees
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "sub1",
|
||||||
|
|
||||||
|
label: (
|
||||||
|
<Link href="http://localhost:3000/organization/overview/multiSig">
|
||||||
|
Multisig
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
icon: <KeyOutlined />,
|
||||||
|
// children: [
|
||||||
|
// { key: "5", label: "Option 5" },
|
||||||
|
// { key: "6", label: "Option 6" },
|
||||||
|
// ],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<div className="flex h-screen flex-col md:flex-row md:overflow-hidden justify-center pl-10 bg-slate-50">
|
||||||
|
<div className="w-full flex-none md:w-24 pt-24">
|
||||||
|
<Menu
|
||||||
|
style={{
|
||||||
|
borderRadius: 8,
|
||||||
|
height: "228px",
|
||||||
|
border: "solid 1px #1677FF",
|
||||||
|
}}
|
||||||
|
defaultSelectedKeys={["1"]}
|
||||||
|
defaultOpenKeys={["sub1"]}
|
||||||
|
mode="inline"
|
||||||
|
theme="light"
|
||||||
|
inlineCollapsed={collapsed}
|
||||||
|
items={items}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex-grow md:overflow-y-auto pt-2">
|
||||||
|
<div className="flex justify-end pt-2 mr-2">
|
||||||
|
<BackBtn />
|
||||||
|
</div>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
49
front/src/app/organization/overview/license/LicensesPage.tsx
Normal file
49
front/src/app/organization/overview/license/LicensesPage.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
"use client";
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { Typography, Button, Card, Input } from "antd";
|
||||||
|
import { WalletOutlined } from "@ant-design/icons";
|
||||||
|
|
||||||
|
const { Title } = Typography;
|
||||||
|
const data = [
|
||||||
|
"1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71",
|
||||||
|
"1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71",
|
||||||
|
"1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71",
|
||||||
|
"1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71",
|
||||||
|
"1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71",
|
||||||
|
];
|
||||||
|
|
||||||
|
export function LicensesPage() {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col w-full p-8 ">
|
||||||
|
<Title style={{ color: "#302d43" }}>Licenses</Title>
|
||||||
|
|
||||||
|
<Card style={{ width: "100%" }}>
|
||||||
|
<div className=" flex flex-row w-full gap-10">
|
||||||
|
<div className="flex flex-col gap-2 w-1/4">
|
||||||
|
<Title level={4}>Owners</Title>
|
||||||
|
<Input placeholder="Name" />
|
||||||
|
<Input placeholder="Name" />
|
||||||
|
<Input placeholder="Name" />
|
||||||
|
<Input placeholder="Name" />
|
||||||
|
<Input placeholder="Name" />
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-2 w-full">
|
||||||
|
<Title level={4}>Shares</Title>
|
||||||
|
|
||||||
|
<Input placeholder="Input information" />
|
||||||
|
<Input placeholder="Input information" />
|
||||||
|
<Input placeholder="Input information" />
|
||||||
|
<Input placeholder="Input information" />
|
||||||
|
<Input placeholder="Input information" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
<div className="flex w-full justify-end mt-5">
|
||||||
|
<Button size={"large"} style={{ width: "150px" }} type="primary">
|
||||||
|
Confirm
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//suffixIcon={<WalletOutlined />}
|
11
front/src/app/organization/overview/license/page.tsx
Normal file
11
front/src/app/organization/overview/license/page.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
"use client";
|
||||||
|
import React from "react";
|
||||||
|
import { LicensesPage } from "./LicensesPage";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<div className="flex w-full h-screen bg-slate-50">
|
||||||
|
<LicensesPage />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -3,8 +3,9 @@ import React, { useState } from "react";
|
|||||||
import { Input } from "antd";
|
import { Input } from "antd";
|
||||||
import { Typography } from "antd";
|
import { Typography } from "antd";
|
||||||
import { Card } from "antd";
|
import { Card } from "antd";
|
||||||
|
import { WalletOutlined } from "@ant-design/icons";
|
||||||
import type { InputNumberProps } from "antd";
|
import type { InputNumberProps } from "antd";
|
||||||
import { Col, InputNumber, Row, Slider, Space, Button } from "antd";
|
import { Col, InputNumber, Row, Slider, Select, Button } from "antd";
|
||||||
|
|
||||||
const { Title } = Typography;
|
const { Title } = Typography;
|
||||||
|
|
||||||
@ -14,14 +15,14 @@ export function MultisigPage() {
|
|||||||
setInputValue(newValue as number);
|
setInputValue(newValue as number);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-full h-full px-28 py-20 gap-10 ">
|
<div className="flex flex-col w-full h-full p-8 gap-10 ">
|
||||||
<div className="flex flex-col w-1/3">
|
<div className="flex flex-col w-1/3">
|
||||||
<Title level={3}>Create a new Multisig</Title>
|
<Title>Create a new Multisig</Title>
|
||||||
<Input size="large" placeholder="Multisig Name/Label" />
|
<Input size="large" placeholder="Multisig Name/Label" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full ">
|
<div className="flex w-full ">
|
||||||
<Card style={{ width: "100%" }}>
|
<Card style={{ width: "100%" }}>
|
||||||
<Title level={4}>Signers</Title>
|
<Title level={4}>Owners</Title>
|
||||||
<div className="flex flex-row gap-5">
|
<div className="flex flex-row gap-5">
|
||||||
<div className="flex flex-col gap-2 w-1/4">
|
<div className="flex flex-col gap-2 w-1/4">
|
||||||
<Input placeholder="Name" />
|
<Input placeholder="Name" />
|
||||||
@ -29,14 +30,32 @@ export function MultisigPage() {
|
|||||||
<Input placeholder="Name" />
|
<Input placeholder="Name" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-2 w-full">
|
<div className="flex flex-col gap-2 w-full">
|
||||||
<Input placeholder="Pubic Key" />
|
<Select
|
||||||
<Input placeholder="Pubic Key" />
|
suffixIcon={<WalletOutlined />}
|
||||||
<Input placeholder="Pubic Key" />
|
defaultValue={""}
|
||||||
|
style={{ width: "full" }}
|
||||||
|
allowClear
|
||||||
|
options={[{ value: "", label: "" }]}
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
suffixIcon={<WalletOutlined />}
|
||||||
|
defaultValue={""}
|
||||||
|
style={{ width: "full" }}
|
||||||
|
allowClear
|
||||||
|
options={[{ value: "", label: "" }]}
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
suffixIcon={<WalletOutlined />}
|
||||||
|
defaultValue={""}
|
||||||
|
style={{ width: "full" }}
|
||||||
|
allowClear
|
||||||
|
options={[{ value: "", label: "" }]}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full justify-end mt-5">
|
<div className="flex w-full justify-end mt-5">
|
||||||
<Button size={"large"} type="primary">
|
<Button size={"large"} type="primary">
|
||||||
Add Signer
|
Add Owner
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
@ -53,7 +72,7 @@ export function MultisigPage() {
|
|||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Slider
|
<Slider
|
||||||
min={1}
|
min={1}
|
||||||
max={20}
|
max={5}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
value={typeof inputValue === "number" ? inputValue : 0}
|
value={typeof inputValue === "number" ? inputValue : 0}
|
||||||
/>
|
/>
|
||||||
@ -61,7 +80,7 @@ export function MultisigPage() {
|
|||||||
<Col span={4}>
|
<Col span={4}>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={1}
|
min={1}
|
||||||
max={20}
|
max={5}
|
||||||
style={{ margin: "0 16px" }}
|
style={{ margin: "0 16px" }}
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
91
front/src/app/organization/overview/pending/PendingPage.tsx
Normal file
91
front/src/app/organization/overview/pending/PendingPage.tsx
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
"use client";
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { Steps, Typography, Card, Input, Space, Button, Select } from "antd";
|
||||||
|
import type { MenuProps } from "antd";
|
||||||
|
import { WalletOutlined } from "@ant-design/icons";
|
||||||
|
const { Title } = Typography;
|
||||||
|
type MenuItem = Required<MenuProps>["items"][number];
|
||||||
|
const data = [
|
||||||
|
"1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71",
|
||||||
|
"1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71",
|
||||||
|
"1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71",
|
||||||
|
"1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71",
|
||||||
|
"1Lbcfr7sAHTD9CgdQo3HTMTkV8LK4ZnX71",
|
||||||
|
];
|
||||||
|
|
||||||
|
export function PendingPage() {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col w-full h-full gap-5 p-8 ">
|
||||||
|
<Title style={{ color: "#302d43" }}>Pending Confirmations</Title>
|
||||||
|
<Steps
|
||||||
|
current={1}
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
title: "Request",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Verify",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Success",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Card className="flex flex-col w-full ">
|
||||||
|
<Space.Compact style={{ width: "100%" }}>
|
||||||
|
<Input
|
||||||
|
size="middle"
|
||||||
|
defaultValue=""
|
||||||
|
placeholder="Pay Out Transaction"
|
||||||
|
/>
|
||||||
|
<Button style={{ color: "#4096ff", borderColor: "#4096ff" }}>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</Space.Compact>
|
||||||
|
|
||||||
|
<div className="flex justify-end mt-5">
|
||||||
|
<Button type="primary" style={{ width: "150px" }}>
|
||||||
|
Execute
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
<Card className="flex flex-col w-full ">
|
||||||
|
<Space.Compact style={{ width: "100%" }}>
|
||||||
|
<Input
|
||||||
|
size="middle"
|
||||||
|
defaultValue=""
|
||||||
|
placeholder="Pay Out Transaction"
|
||||||
|
/>
|
||||||
|
<Button style={{ color: "#4096ff", borderColor: "#4096ff" }}>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</Space.Compact>
|
||||||
|
|
||||||
|
<div className="flex justify-end mt-5">
|
||||||
|
<Button type="primary" style={{ width: "150px" }}>
|
||||||
|
Execute
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
<Card className="flex flex-col w-full ">
|
||||||
|
<Space.Compact style={{ width: "100%" }}>
|
||||||
|
<Input
|
||||||
|
size="middle"
|
||||||
|
defaultValue=""
|
||||||
|
placeholder="Pay Out Transaction"
|
||||||
|
/>
|
||||||
|
<Button style={{ color: "#4096ff", borderColor: "#4096ff" }}>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</Space.Compact>
|
||||||
|
|
||||||
|
<div className="flex justify-end mt-5">
|
||||||
|
<Button type="primary" style={{ width: "150px" }}>
|
||||||
|
Execute
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
11
front/src/app/organization/overview/pending/page.tsx
Normal file
11
front/src/app/organization/overview/pending/page.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
"use client";
|
||||||
|
import React from "react";
|
||||||
|
import { PendingPage } from "./PendingPage";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<div className="flex w-full h-screen items-center justify-center bg-slate-50">
|
||||||
|
<PendingPage />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { OrgCreatePage } from "./OrgCreatePage";
|
import { OrgCreatePage } from "../orgCreate/OrgCreatePage";
|
||||||
// вместо этого надо класть большие компоненты
|
|
||||||
|
|
||||||
export default function organization() {
|
export default function organization() {
|
||||||
return (
|
return (
|
||||||
|
20
front/src/app/ui/BackBtn.tsx
Normal file
20
front/src/app/ui/BackBtn.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
"use client";
|
||||||
|
import { Button } from "antd";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { ArrowLeftOutlined } from "@ant-design/icons";
|
||||||
|
export function BackBtn() {
|
||||||
|
const router = useRouter();
|
||||||
|
const goBack = () => {
|
||||||
|
router.back();
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="flex items-center"
|
||||||
|
type="text"
|
||||||
|
size="large"
|
||||||
|
onClick={goBack}
|
||||||
|
>
|
||||||
|
<ArrowLeftOutlined />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
14
front/src/app/ui/PayOutBtn.tsx
Normal file
14
front/src/app/ui/PayOutBtn.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
"use client";
|
||||||
|
import { Button } from "antd";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
export function PayOutBtn() {
|
||||||
|
const router = useRouter();
|
||||||
|
const onPayHandler = () => {
|
||||||
|
router.push("/organization/overview/pending");
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Button onClick={onPayHandler} type="primary">
|
||||||
|
Pay Out
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
@ -2,14 +2,11 @@ import { useState } from "react";
|
|||||||
|
|
||||||
export default function useLoginHooks() {
|
export default function useLoginHooks() {
|
||||||
const [passwordVisible, setPasswordVisible] = useState([]);
|
const [passwordVisible, setPasswordVisible] = useState([]);
|
||||||
const [seed, setSeed] = useState<string[]>([]);
|
|
||||||
|
|
||||||
const getSeed = (string: string) => {
|
// const getSeed = (string: string) => {
|
||||||
if (seed.length < 12) {
|
// // if (seed.length < 12) {
|
||||||
setSeed((prev) => [...prev, string]);
|
// setSeed((prev) => [...prev, string]);
|
||||||
}
|
// };
|
||||||
};
|
|
||||||
console.log(seed);
|
|
||||||
|
|
||||||
return { passwordVisible, setPasswordVisible, seed, getSeed };
|
return { passwordVisible, setPasswordVisible };
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user