diff --git a/admin/.eslintrc.json b/admin/.eslintrc.json new file mode 100644 index 000000000..bffb357a7 --- /dev/null +++ b/admin/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/admin/.gitignore b/admin/.gitignore new file mode 100644 index 000000000..31c7e392e --- /dev/null +++ b/admin/.gitignore @@ -0,0 +1,37 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +.vscode \ No newline at end of file diff --git a/admin/.npmrc b/admin/.npmrc new file mode 100644 index 000000000..415dafa69 --- /dev/null +++ b/admin/.npmrc @@ -0,0 +1 @@ +registry=https://registry.yarnpkg.com/ \ No newline at end of file diff --git a/admin/README.md b/admin/README.md new file mode 100644 index 000000000..7bcbf23de --- /dev/null +++ b/admin/README.md @@ -0,0 +1,7 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +yarn dev diff --git a/admin/next.config.js b/admin/next.config.js new file mode 100644 index 000000000..70facc4f6 --- /dev/null +++ b/admin/next.config.js @@ -0,0 +1,33 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + experimental: { + appDir: true, + }, + swcMinify: true, + compiler: { + styledComponents: true, + removeConsole: process.env.NODE_ENV === "production", + }, + webpack(config) { + config.module.rules.push({ + test: /\.svg$/, + use: ["@svgr/webpack"], + }); + + return config; + }, + webpackDevMiddleware: (config) => { + config.watchOptions = { + poll: 1000, + aggregateTimeout: 300, + }; + return config; + }, + swcMinify: true, +}; +// const withBundleAnalyzer = require("@next/bundle-analyzer")({ +// enabled: process.env.ANALYZE === "true", +// }); + +// module.exports = withBundleAnalyzer(nextConfig); +module.exports = nextConfig; diff --git a/admin/package.json b/admin/package.json new file mode 100644 index 000000000..e7e04b0d0 --- /dev/null +++ b/admin/package.json @@ -0,0 +1,36 @@ +{ + "name": "admin", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@emotion/react": "^11.11.0", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.11.16", + "@mui/material": "^5.13.0", + "@mui/styled-engine-sc": "^5.12.0", + "@next/font": "^13.3.1", + "@types/node": "18.16.0", + "@types/react": "18.0.38", + "@types/react-dom": "18.0.11", + "@types/react-virtualized": "^9.21.21", + "@types/styled-components": "^5.1.26", + "axios": "^1.3.6", + "eslint": "8.39.0", + "eslint-config-next": "13.3.1", + "next": "13.3.1", + "react": "18.2.0", + "react-dom": "18.2.0", + "react-query": "^3.39.3", + "styled-components": "^6.0.0-rc.1", + "typescript": "5.0.4" + }, + "resolutions": { + "styled-components": "^5" + } +} diff --git a/admin/public/fonts/EliceDigitalBaeumOTF_Bold.otf b/admin/public/fonts/EliceDigitalBaeumOTF_Bold.otf new file mode 100644 index 000000000..b661662e2 Binary files /dev/null and b/admin/public/fonts/EliceDigitalBaeumOTF_Bold.otf differ diff --git a/admin/public/fonts/EliceDigitalBaeumOTF_Regular.otf b/admin/public/fonts/EliceDigitalBaeumOTF_Regular.otf new file mode 100644 index 000000000..d7f524551 Binary files /dev/null and b/admin/public/fonts/EliceDigitalBaeumOTF_Regular.otf differ diff --git a/admin/public/fonts/Pretendard.woff2 b/admin/public/fonts/Pretendard.woff2 new file mode 100644 index 000000000..aeb16e61e Binary files /dev/null and b/admin/public/fonts/Pretendard.woff2 differ diff --git a/admin/public/next.svg b/admin/public/next.svg new file mode 100644 index 000000000..5174b28c5 --- /dev/null +++ b/admin/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/public/vercel.svg b/admin/public/vercel.svg new file mode 100644 index 000000000..d2f842227 --- /dev/null +++ b/admin/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/src/app/favicon.ico b/admin/src/app/favicon.ico new file mode 100644 index 000000000..dbf593335 Binary files /dev/null and b/admin/src/app/favicon.ico differ diff --git a/admin/src/app/getQueryClient.tsx b/admin/src/app/getQueryClient.tsx new file mode 100644 index 000000000..c9ad4b45d --- /dev/null +++ b/admin/src/app/getQueryClient.tsx @@ -0,0 +1,5 @@ +import { cache } from "react"; +import { QueryClient } from "react-query"; + +const getQueryClient = cache(() => new QueryClient()); +export default getQueryClient; diff --git a/admin/src/app/head.tsx b/admin/src/app/head.tsx new file mode 100644 index 000000000..d2bfab4d7 --- /dev/null +++ b/admin/src/app/head.tsx @@ -0,0 +1,13 @@ +export default function Head() { + return ( + <> + Orakl Network + + + + + ); +} diff --git a/admin/src/app/layout.tsx b/admin/src/app/layout.tsx new file mode 100644 index 000000000..9d5994d56 --- /dev/null +++ b/admin/src/app/layout.tsx @@ -0,0 +1,29 @@ +"use client"; + +import { ThemeProvider } from "@mui/material"; +import "../theme/globals.css"; +import { Inter } from "next/font/google"; +import { theme } from "@/theme/theme"; +import QueryClientProviders from "./provider"; +import RootStyleRegistry from "@/lib/RootStyleRegistry"; + +const inter = Inter({ subsets: ["latin"] }); + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + + + {children} + + + + + ); +} diff --git a/admin/src/app/page.tsx b/admin/src/app/page.tsx new file mode 100644 index 000000000..9550f187f --- /dev/null +++ b/admin/src/app/page.tsx @@ -0,0 +1,13 @@ +"use client"; + +import Header from "@/components/Common/Header"; +import HomeTemplate from "@/components/Template/Home"; + +export default function Home() { + return ( + <> +
+ + + ); +} diff --git a/admin/src/app/provider.tsx b/admin/src/app/provider.tsx new file mode 100644 index 000000000..f1a456f16 --- /dev/null +++ b/admin/src/app/provider.tsx @@ -0,0 +1,16 @@ +"use client"; + +import React from "react"; +import { QueryClient, QueryClientProvider } from "react-query"; + +export default function QueryClientProviders({ + children, +}: { + children: React.ReactNode; +}) { + const [queryClient] = React.useState(() => new QueryClient()); + + return ( + {children} + ); +} diff --git a/admin/src/components/Common/Accordion/AccordionSummary/index.tsx b/admin/src/components/Common/Accordion/AccordionSummary/index.tsx new file mode 100644 index 000000000..6b2b1386a --- /dev/null +++ b/admin/src/components/Common/Accordion/AccordionSummary/index.tsx @@ -0,0 +1,31 @@ +import * as React from "react"; +import { styled } from "@mui/material/styles"; +import ArrowForwardIosSharpIcon from "@mui/icons-material/ArrowForwardIosSharp"; +import MuiAccordionSummary, { + AccordionSummaryProps, +} from "@mui/material/AccordionSummary"; +import { Accordion } from "@mui/material"; + +const AccordionSummary = styled((props: AccordionSummaryProps) => ( + } + {...props} + /> +))(({ theme }) => ({ + backgroundColor: "rgba(60, 67, 74, 1)", + color: "white", + "&:hover": { + backgroundColor: "#fef1cc", + color: "black", + }, + + flexDirection: "row-reverse", + "& .MuiAccordionSummary-expandIconWrapper.Mui-expanded": { + transform: "rotate(90deg)", + }, + "& .MuiAccordionSummary-content": { + marginLeft: theme.spacing(1), + }, +})); + +export default AccordionSummary; diff --git a/admin/src/components/Common/Accordion/AccordionWrap/index.tsx b/admin/src/components/Common/Accordion/AccordionWrap/index.tsx new file mode 100644 index 000000000..33920ae96 --- /dev/null +++ b/admin/src/components/Common/Accordion/AccordionWrap/index.tsx @@ -0,0 +1,19 @@ +import * as React from "react"; +import { styled } from "@mui/material/styles"; +import MuiAccordion, { AccordionProps } from "@mui/material/Accordion"; + +const AccordionWrap = styled((props: AccordionProps) => ( + +))(({ theme }) => ({ + color: "#fef1cc", + border: `1px solid ${theme.palette.divider}`, + backgroundColor: "rgba(60, 67, 74, 1)", + "&:not(:last-child)": { + borderBottom: 0, + }, + "&:before": { + display: "none", + }, +})); + +export default AccordionWrap; diff --git a/admin/src/components/Common/Accordion/index.tsx b/admin/src/components/Common/Accordion/index.tsx new file mode 100644 index 000000000..3c9b9b391 --- /dev/null +++ b/admin/src/components/Common/Accordion/index.tsx @@ -0,0 +1,61 @@ +import * as React from "react"; +import { styled } from "@mui/material/styles"; +import MuiAccordionDetails from "@mui/material/AccordionDetails"; +import Typography from "@mui/material/Typography"; +import { AccordionContainer, AccordionDetails } from "./styled"; +import AccordionWrap from "./AccordionWrap"; +import AccordionSummary from "./AccordionSummary"; +import BasicButton from "../BasicButton"; + +export default function CustomizedAccordions() { + const [expanded, setExpanded] = React.useState("panel1"); + + const handleChange = + (panel: string) => (event: React.SyntheticEvent, newExpanded: boolean) => { + setExpanded(newExpanded ? panel : false); + }; + + return ( + + + + First data + + + + + + + + + + Second data + + + + + + + + + + Third data + + + + + + + + + ); +} diff --git a/admin/src/components/Common/Accordion/styled.ts b/admin/src/components/Common/Accordion/styled.ts new file mode 100644 index 000000000..5cd39b8eb --- /dev/null +++ b/admin/src/components/Common/Accordion/styled.ts @@ -0,0 +1,14 @@ +import { styled } from "@mui/material/styles"; +import { theme } from "@/theme/theme"; + +export const AccordionContainer = styled("div")({ + width: "20%", + height: "100%", + marginTop: "100px", + background: theme.palette.primary.main, +}); +export const AccordionDetails = styled("div")(({ theme }) => ({ + borderTop: "1px solid rgba(0, 0, 0, .125)", + display: "flex", + flexDirection: "column", +})); diff --git a/admin/src/components/Common/BasicButton/index.tsx b/admin/src/components/Common/BasicButton/index.tsx new file mode 100644 index 000000000..ba047a3ca --- /dev/null +++ b/admin/src/components/Common/BasicButton/index.tsx @@ -0,0 +1,33 @@ +import * as React from "react"; +import Button, { ButtonProps } from "@mui/material/Button"; + +interface BasicButtonProps extends ButtonProps { + text: string; + disabled?: boolean; + justifyContent?: string; + width?: string; +} + +export default function BasicButton({ + text, + onClick, + color = "primary", + variant = "contained", + disabled = false, + justifyContent = "flex-start", + width = "100%", + ...rest +}: BasicButtonProps) { + return ( + + ); +} diff --git a/admin/src/components/Common/BasicButton/styled.ts b/admin/src/components/Common/BasicButton/styled.ts new file mode 100644 index 000000000..f2b192328 --- /dev/null +++ b/admin/src/components/Common/BasicButton/styled.ts @@ -0,0 +1,5 @@ +import { styled } from "styled-components"; + +export const ButtonContainer = styled.div<{ textAlign?: string }>` + text-align: ${({ textAlign }) => textAlign}; +`; diff --git a/admin/src/components/Common/Header/index.tsx b/admin/src/components/Common/Header/index.tsx new file mode 100644 index 000000000..e0c6a9499 --- /dev/null +++ b/admin/src/components/Common/Header/index.tsx @@ -0,0 +1,5 @@ +import { HeaderContainer } from "./styled"; + +export default function Header(): JSX.Element { + return Orakl Admin; +} diff --git a/admin/src/components/Common/Header/styled.ts b/admin/src/components/Common/Header/styled.ts new file mode 100644 index 000000000..a1279969d --- /dev/null +++ b/admin/src/components/Common/Header/styled.ts @@ -0,0 +1,13 @@ +import styled from "styled-components"; + +export const HeaderContainer = styled.header` + background-color: #212a3e; + min-height: 10vh; + display: flex; + font-size: 22px; + flex-direction: row; + align-items: center; + justify-content: space-between; + color: white; + padding: 0 2rem; +`; diff --git a/admin/src/components/Common/NavigationDropdown/index.tsx b/admin/src/components/Common/NavigationDropdown/index.tsx new file mode 100644 index 000000000..44c059f3a --- /dev/null +++ b/admin/src/components/Common/NavigationDropdown/index.tsx @@ -0,0 +1,67 @@ +import React, { useState } from "react"; +import styled from "styled-components"; +import Button from "../BasicButton"; +import { + NavDropdownContainer, + AccordionContainer, + AccordionItem, + AccordionHeader, + AccordionContent, + Icon, +} from "./styled"; + +export default function NavigationDropdown(): JSX.Element { + const [isAccordionOpen, setIsAccordionOpen] = useState([true, true, true]); + + function handleAccordionToggle(index: number) { + setIsAccordionOpen((isOpen) => ({ ...isOpen, [index]: !isOpen[index] })); + } + + return ( + + + + handleAccordionToggle(0)}> + Configuration + {isAccordionOpen[0] ? "-" : "+"} + + {isAccordionOpen[0] && ( + +