From b631206c4430a968e3c686354049efd9918b6690 Mon Sep 17 00:00:00 2001 From: Primakov Alexandr Alexandrovich Date: Thu, 24 Oct 2024 20:04:54 +0300 Subject: [PATCH] params in url + error boundary --- bro.config.js | 2 +- package-lock.json | 221 ++++++++++++++++++++++++++++++ package.json | 2 + src/__data__/urls.ts | 4 +- src/app.tsx | 9 +- src/components/error-boundary.tsx | 24 ++++ src/dashboard.tsx | 5 +- src/index.tsx | 2 +- src/pages/about/about.style.ts | 18 +++ src/pages/about/about.tsx | 17 ++- src/pages/about/components.tsx | 3 + src/pages/profile/profile.tsx | 6 +- tags.js | 28 ++++ types/emotion.d.ts | 9 ++ 14 files changed, 337 insertions(+), 13 deletions(-) create mode 100644 src/components/error-boundary.tsx create mode 100644 src/pages/about/about.style.ts create mode 100644 src/pages/about/components.tsx create mode 100644 tags.js create mode 100644 types/emotion.d.ts diff --git a/bro.config.js b/bro.config.js index 4cd6696..4e05c83 100644 --- a/bro.config.js +++ b/bro.config.js @@ -11,7 +11,7 @@ module.exports = { navigations: { "nav1.main": "/nav1", "link.nav1.about": "/", - "link.nav1.profile": "/my-best-profile-page-ever", + "link.nav1.profile": "/my-best-profile-page-ever/:userId/:projectId", "nav2.main": "/nav2", }, features: { diff --git a/package-lock.json b/package-lock.json index aa7c119..b813545 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,8 @@ "license": "ISC", "dependencies": { "@brojs/cli": "^1.3.0", + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "express": "^4.19.2", @@ -1828,6 +1830,167 @@ "webpack-merge": "5.7.2" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", + "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.13.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", + "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", + "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", + "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2444,6 +2607,37 @@ "webpack": ">=5" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", @@ -3667,6 +3861,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, "node_modules/find-up": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", @@ -4250,6 +4450,15 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/html-entities": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", @@ -5844,6 +6053,12 @@ } } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/react-router": { "version": "6.27.0", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", @@ -6514,6 +6729,12 @@ "webpack": "^5.27.0" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", diff --git a/package.json b/package.json index 386dbf1..2259dcb 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "description": "", "dependencies": { "@brojs/cli": "^1.3.0", + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "express": "^4.19.2", diff --git a/src/__data__/urls.ts b/src/__data__/urls.ts index 351601d..e8c6abc 100644 --- a/src/__data__/urls.ts +++ b/src/__data__/urls.ts @@ -7,8 +7,8 @@ export const URLs = { profile: { isOn: Boolean(getNavigationsValue("link.nav1.profile")), url: `${baseUrl}${getNavigationsValue("link.nav1.profile")}`, - getUrl() { - return this.url; + getUrl(userId: string, projectId: string) { + return generatePath(this.url, { userId, projectId }); }, }, about: { diff --git a/src/app.tsx b/src/app.tsx index 98b995d..49dd6f2 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,13 +1,16 @@ import React from 'react'; import { BrowserRouter, HashRouter } from 'react-router-dom'; +import { ThemeProvider } from '@emotion/react' import { Dashboard } from './dashboard'; const App = () => { return ( - - - + + + + + ); }; diff --git a/src/components/error-boundary.tsx b/src/components/error-boundary.tsx new file mode 100644 index 0000000..c30395a --- /dev/null +++ b/src/components/error-boundary.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +export class ErrorBoundary extends React.Component<{ children: React.ReactNode }, { hasError: boolean }> { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + + componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void { + + } + + static getDerivedStateFromError(error) { + return { + hasError: true + } + } + + render() { + const { hasError } = this.state + + return hasError ?
Something went wrong
: this.props.children; + } +} \ No newline at end of file diff --git a/src/dashboard.tsx b/src/dashboard.tsx index e401540..4607f4f 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -3,9 +3,12 @@ import { Routes, Route } from "react-router-dom"; import { URLs } from "./__data__/urls"; import { ProfilePage, AboutPage } from "./pages"; +import { ErrorBoundary } from "./components/error-boundary"; const PageWrapper = ({ children }) => ( - Loading...}>{children} + + Loading...}>{children} + ); export const Dashboard = () => { diff --git a/src/index.tsx b/src/index.tsx index 738c4e0..5ac0e9f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,7 +2,7 @@ /* eslint-disable react/display-name */ import React from 'react'; import ReactDOM from 'react-dom/client'; - + import App from './app'; export default () => ; diff --git a/src/pages/about/about.style.ts b/src/pages/about/about.style.ts new file mode 100644 index 0000000..2d998ad --- /dev/null +++ b/src/pages/about/about.style.ts @@ -0,0 +1,18 @@ +import styled from '@emotion/styled' + +import { Header } from './components' + +export const StyledHeader = styled(Header)` + padding-top: 100px; +`; + +export const Wrapper = styled.div<{ red?: boolean }>` + max-width: 800px; + margin: 0 auto; + background-color: ${(props) => props.red ? 'red' : props.theme.colors.main}; + + ${StyledHeader.toString()} { + color: palevioletred; + } +`; + diff --git a/src/pages/about/about.tsx b/src/pages/about/about.tsx index ce804f5..04a191f 100644 --- a/src/pages/about/about.tsx +++ b/src/pages/about/about.tsx @@ -3,11 +3,20 @@ import { Link } from "react-router-dom"; import { URLs } from "../../__data__/urls"; +import { StyledHeader, Wrapper } from "./about.style"; +import { Header } from "./components"; + export const AboutPage = () => { return ( -
-

about page

- {URLs.profile.isOn && go to profile page} -
+ <> + + + +
+ {URLs.profile.isOn && ( + go to profile page + )} + + ); }; diff --git a/src/pages/about/components.tsx b/src/pages/about/components.tsx new file mode 100644 index 0000000..a9f8ddf --- /dev/null +++ b/src/pages/about/components.tsx @@ -0,0 +1,3 @@ +import React from "react"; + +export const Header = ({ className }: { className?: string }) =>

about page

diff --git a/src/pages/profile/profile.tsx b/src/pages/profile/profile.tsx index b246cc2..5ab04e7 100644 --- a/src/pages/profile/profile.tsx +++ b/src/pages/profile/profile.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Link } from "react-router-dom"; +import { Link, useParams } from "react-router-dom"; import { getHistory } from '@brojs/cli' import { getNavigationsValue } from "@brojs/cli"; @@ -13,6 +13,8 @@ export const ProfilePage = () => { history.push(getNavigationsValue('nav2.main')); } + const params = useParams<{ userId: string, prodileId: string }>(); + return (

profile page

@@ -21,6 +23,8 @@ export const ProfilePage = () => { + +
{JSON.stringify(params as Required, null, 4)}
); }; diff --git a/tags.js b/tags.js new file mode 100644 index 0000000..c775bab --- /dev/null +++ b/tags.js @@ -0,0 +1,28 @@ +const makeStyles = (theme) => (body, ...expressions) => { + console.log(body, expressions); + return body.reduce((acc, cur, index) => { + const expression = expressions[index]; + + if (typeof expression === "function") { + cur += expression(theme); + } else if (expression) { + cur += expression; + } + + acc += cur; + + return acc; + }, ""); +}; + +let condition = false; + +const css = makeStyles({ colors: { main: 'red', notmain: 'green' } }) + +const styles = css` + width: 100%; + color: ${condition ? "red" : "green"}; + background-color: ${(theme) => condition ? theme.colors.main : theme.colors.notmain}; +`; + +console.log("styles", styles); diff --git a/types/emotion.d.ts b/types/emotion.d.ts new file mode 100644 index 0000000..820506a --- /dev/null +++ b/types/emotion.d.ts @@ -0,0 +1,9 @@ +import '@emotion/react' + +declare module '@emotion/react' { + export interface Theme { + colors: { + main: string + } + } +}