From 45e36b2360d7f2be9a0304854109db9d0d449360 Mon Sep 17 00:00:00 2001 From: Pavel <14926950+prichodko@users.noreply.github.com> Date: Wed, 21 Jun 2023 12:35:48 +0200 Subject: [PATCH] [website] Add blog (#417) * add ghost api * connect blog overview page * connect and render post detail * add processing to server * update blog detail page * add eslint-plugin-tailwindcss * add @tanstack/react-query * truncate text by numberOfLines * use ComponentPropsWithRef to infer style prop type * update ghost fns * update index * add tag page * add author page * update / * update /tag * update /author * update detail page * fix posts type * disable redirect * remove global background - not found pages - pages without common layout (preview) * tmp: hide nav on smaller screens * update app layout spacing * remove text truncating * update / spacing and sizing * update .vscode/settings.json * update .eslintrc * update prettier-plugin-tailwindcss * sort tailwind classes * add packages/eslint-config-custom * use turbo lint * use tailwind.config.cjs see https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/212 * reset global line-height * fix lint-staged * update color tokens * update spacing and sizes * Update apps/website/src/lib/ghost.ts Co-authored-by: Pavel <14926950+prichodko@users.noreply.github.com> * update layout max width * update card min width * set line-height * set overflow on pre * use flex for markdown content to prevent overflow * collect follow-ups * add visibility filter * update page count * rename var * remove filter * use prod ghost api key * update ghost api * revert line-height * add limit to getPosts params * update visible posts * add related articles * add env vars to gh * rename eslint config package * update gh vars * rename envs * set emtpy array to related posts * fix lint-staged * prevent importing server envs on client * set limit --------- Co-authored-by: Felicio Mununga --- .eslintrc | 119 ---- .github/workflows/ci.yml | 5 + .vscode/settings.json | 8 +- apps/mobile/.eslintrc | 4 + apps/mobile/package.json | 1 + apps/web/.eslintrc | 9 + apps/web/package.json | 1 + apps/website/.env | 1 - apps/website/.eslintrc | 9 + apps/website/.prettierrc | 6 + apps/website/env.d.ts | 5 +- apps/website/next.config.mjs | 3 +- apps/website/package.json | 12 +- .../website/public/images/social/facebook.svg | 22 + apps/website/public/images/social/reddit.svg | 19 + apps/website/public/images/social/status.svg | 108 +++ apps/website/public/images/social/twitter.svg | 12 + apps/website/src/components/link.tsx | 4 +- apps/website/src/components/logo.tsx | 2 +- apps/website/src/components/nav-menu.tsx | 8 +- apps/website/src/components/page-footer.tsx | 2 +- .../src/components/side-bar/side-bar.tsx | 2 +- apps/website/src/components/table-issues.tsx | 8 +- apps/website/src/config/env.client.mjs | 9 + apps/website/src/config/env.mjs | 8 - apps/website/src/config/env.server.mjs | 15 + apps/website/src/layouts/app-layout.tsx | 16 +- apps/website/src/layouts/insights-layout.tsx | 2 +- apps/website/src/lib/ethereum-client.ts | 4 +- apps/website/src/lib/ghost.ts | 98 +++ apps/website/src/pages/blog/[slug].tsx | 246 ++++++- apps/website/src/pages/blog/author/[slug].tsx | 137 ++++ apps/website/src/pages/blog/index.tsx | 247 +++++-- apps/website/src/pages/blog/tag/[slug].tsx | 132 ++++ apps/website/src/pages/index.tsx | 14 +- .../src/pages/insights/epics/[epic].tsx | 4 +- apps/website/src/pages/insights/repos.tsx | 2 +- .../insights/workstreams/[workstream].tsx | 4 +- apps/website/src/styles/global.css | 6 - ...tailwind.config.js => tailwind.config.cjs} | 2 +- package.json | 21 +- packages/colors/.eslintrc | 4 + packages/colors/package.json | 1 + packages/components/.eslintrc | 4 + packages/components/package.json | 1 + packages/components/src/tokens.ts | 14 +- packages/eslint-config-custom/index.js | 104 +++ packages/eslint-config-custom/package.json | 31 + packages/icons/.eslintrc | 4 + packages/icons/package.json | 1 + packages/status-js/.eslintrc | 13 + packages/status-js/package.json | 1 + packages/status-react/.eslintrc | 4 + packages/status-react/package.json | 1 + yarn.lock | 632 ++++++++++++++---- 55 files changed, 1787 insertions(+), 365 deletions(-) delete mode 100644 .eslintrc create mode 100644 apps/mobile/.eslintrc create mode 100644 apps/web/.eslintrc create mode 100644 apps/website/.eslintrc create mode 100644 apps/website/.prettierrc create mode 100644 apps/website/public/images/social/facebook.svg create mode 100644 apps/website/public/images/social/reddit.svg create mode 100644 apps/website/public/images/social/status.svg create mode 100644 apps/website/public/images/social/twitter.svg create mode 100644 apps/website/src/config/env.client.mjs delete mode 100644 apps/website/src/config/env.mjs create mode 100644 apps/website/src/config/env.server.mjs create mode 100644 apps/website/src/lib/ghost.ts create mode 100644 apps/website/src/pages/blog/author/[slug].tsx create mode 100644 apps/website/src/pages/blog/tag/[slug].tsx rename apps/website/{tailwind.config.js => tailwind.config.cjs} (98%) create mode 100644 packages/colors/.eslintrc create mode 100644 packages/components/.eslintrc create mode 100644 packages/eslint-config-custom/index.js create mode 100644 packages/eslint-config-custom/package.json create mode 100644 packages/icons/.eslintrc create mode 100644 packages/status-js/.eslintrc create mode 100644 packages/status-react/.eslintrc diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index d6903d5c..00000000 --- a/.eslintrc +++ /dev/null @@ -1,119 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - // TODO: Enable type-aware linting (https://typescript-eslint.io/docs/linting/type-linting) - // "tsconfigRootDir": ".", - // "project": ["./packages/*/tsconfig.json"], - "sourceType": "module", - "ecmaFeatures": { - "jsx": true - }, - "warnOnUnsupportedTypeScriptVersion": true - }, - "env": { - "browser": true, - "node": true - }, - "plugins": [ - "@typescript-eslint", - "import", - "simple-import-sort", - "react", - "jsx-a11y" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - // "plugin:@typescript-eslint/recommended-requiring-type-checking", - "plugin:eslint-comments/recommended", - "plugin:import/recommended", - "plugin:import/typescript", - "plugin:jsx-a11y/recommended", - "plugin:react/recommended", - "plugin:react-hooks/recommended", - "plugin:react/jsx-runtime", - "prettier" - ], - "overrides": [ - { - "files": ["examples/**/*.tsx"], - "rules": { - "react/jsx-uses-react": "off", - "react/react-in-jsx-scope": "off" - } - }, - { - // TODO: add https://github.com/francoismassart/eslint-plugin-tailwindcss - "files": ["./apps/website/"], - "extends": ["next", "next/core-web-vitals"] - // "settings": { - // "import/resolver": { - // "typescript": { - // "extensions": [".js", ".jsx", ".ts", ".tsx"], - // "project": ["tsconfig.json", "apps/website/tsconfig.json"] - // } - // } - // } - } - ], - "rules": { - "react/prop-types": 0, - // "@typescript-eslint/consistent-type-definitions": ["error", "interface"], - "@typescript-eslint/consistent-type-imports": "error", - // TODO: turn on this rul - "@typescript-eslint/no-non-null-assertion": "off", - // "@typescript-eslint/consistent-type-exports": "error", - "simple-import-sort/imports": [ - "error", - { - "groups": [ - // Side effect imports. - ["^\\u0000"], - // `react` related packages come first. - ["^react$", "^react-dom$"], - // Things that start with a letter (or digit or underscore), or `@` followed by a letter. - ["^@?\\w"], - // Absolute imports and other imports such as Vue-style `@/foo`. - // Anything not matched in another group. - ["^"], - // Relative imports. - // Anything that starts with a dot. - ["^\\."], - // type imports last as a separate group - ["^.+\\u0000$"] - ] - } - ], - "simple-import-sort/exports": "error", - "import/first": "error", - "import/newline-after-import": "error", - "import/no-duplicates": "error" - }, - "settings": { - "react": { - "version": "detect" - }, - "import/resolver": { - "node": { - "extensions": [".js", ".jsx", ".ts", ".tsx"], - "project": [ - "tsconfig.base.json", - "packages/*/tsconfig.json", - "apps/*/tsconfig.json" - ] - }, - "typescript": { - "alwaysTryTypes": true, - "project": [ - "tsconfig.base.json", - "packages/*/tsconfig.json", - "apps/*/tsconfig.json" - ] - } - }, - "import/ignore": ["react-native"] - } -} - -// appp/website; extend eslint-config-next diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2677bae..d9fd83f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,11 @@ on: pull_request: types: [opened, synchronize] +env: + NEXT_PUBLIC_GHOST_API_KEY: '' + INFURA_API_KEY: '' + TAMAGUI_TARGET: 'web' + jobs: build: name: Build and Test diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c53bbc..a7375cd5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,11 @@ { "typescript.tsdk": "node_modules/typescript/lib", "eslint.packageManager": "yarn", - "npm.packageManager": "yarn" + "npm.packageManager": "yarn", + "eslint.workingDirectories": [ + { + "mode": "auto", + "#comment": "See https://github.com/microsoft/vscode-eslint/issues/1161 for reason (i.e. multiple .eslintrc config files)" + } + ] } diff --git a/apps/mobile/.eslintrc b/apps/mobile/.eslintrc new file mode 100644 index 00000000..bef97c7d --- /dev/null +++ b/apps/mobile/.eslintrc @@ -0,0 +1,4 @@ +{ + "root": true, + "extends": ["@status-im/eslint-config"] +} diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 54966df6..a8a7c5c7 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -38,6 +38,7 @@ "@types/react-native": "~0.70.6", "babel-plugin-module-resolver": "^4.1.0", "babel-plugin-transform-inline-environment-variables": "^0.4.4", + "@status-im/eslint-config": "*", "typescript": "^5.0.3" } } diff --git a/apps/web/.eslintrc b/apps/web/.eslintrc new file mode 100644 index 00000000..51442486 --- /dev/null +++ b/apps/web/.eslintrc @@ -0,0 +1,9 @@ +{ + "root": true, + "extends": [ + "@status-im/eslint-config", + "plugin:tailwindcss/recommended", + "next", + "next/core-web-vitals" + ] +} diff --git a/apps/web/package.json b/apps/web/package.json index dd2f98fa..a02f5923 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -24,6 +24,7 @@ "@types/react": "^18.0.33", "@types/react-dom": "^18.0.11", "@vitejs/plugin-react-swc": "^3.2.0", + "@status-im/eslint-config": "*", "typescript": "^5.0.3", "vite": "^4.2.1" } diff --git a/apps/website/.env b/apps/website/.env index c5aff7bd..8a7fcfdd 100644 --- a/apps/website/.env +++ b/apps/website/.env @@ -1,4 +1,3 @@ IGNORE_TS_CONFIG_PATHS=true TAMAGUI_TARGET=web TAMAGUI_DISABLE_WARN_DYNAMIC_LOAD=1 - diff --git a/apps/website/.eslintrc b/apps/website/.eslintrc new file mode 100644 index 00000000..51442486 --- /dev/null +++ b/apps/website/.eslintrc @@ -0,0 +1,9 @@ +{ + "root": true, + "extends": [ + "@status-im/eslint-config", + "plugin:tailwindcss/recommended", + "next", + "next/core-web-vitals" + ] +} diff --git a/apps/website/.prettierrc b/apps/website/.prettierrc new file mode 100644 index 00000000..2ec5b2fc --- /dev/null +++ b/apps/website/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": false, + "singleQuote": true, + "arrowParens": "avoid", + "tailwindConfig": "./tailwind.config.cjs" +} diff --git a/apps/website/env.d.ts b/apps/website/env.d.ts index 3870ac51..0bd9db58 100644 --- a/apps/website/env.d.ts +++ b/apps/website/env.d.ts @@ -1,6 +1,7 @@ -import type { env } from './src/config/env.mjs' +import type { clientEnv } from './src/config/env.client.mjs' +import type { serverEnv } from './src/config/env.server.mjs' -type Env = typeof env +type Env = typeof clientEnv & typeof serverEnv declare global { namespace NodeJS { diff --git a/apps/website/next.config.mjs b/apps/website/next.config.mjs index 0bed29ea..15137965 100644 --- a/apps/website/next.config.mjs +++ b/apps/website/next.config.mjs @@ -1,7 +1,8 @@ /* eslint-disable eslint-comments/disable-enable-pair */ /* eslint-disable import/default */ -import './src/config/env.mjs' +import './src/config/env.server.mjs' +import './src/config/env.client.mjs' import tamagui_next_plugin from '@tamagui/next-plugin' import { join } from 'node:path' diff --git a/apps/website/package.json b/apps/website/package.json index a8b5f4b2..4e7f873c 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -8,7 +8,7 @@ "start": "next start", "lint": "next lint", "typecheck": "tsc", - "clean": "rimraf .next .tamagui .vercel/output node_modules .turbo", + "clean": "rimraf .next .tamagui .turbo .vercel/output node_modules", "preview": "next start --port 8151" }, "dependencies": { @@ -23,6 +23,7 @@ "@tamagui/next-theme": "1.11.1", "@tanstack/react-query": "^4.29.7", "@vercel/og": "^0.5.4", + "@tryghost/content-api": "^1.11.13", "@visx/visx": "^2.18.0", "class-variance-authority": "^0.6.0", "d3-array": "^3.2.3", @@ -37,17 +38,24 @@ }, "devDependencies": { "@achingbrain/ssdp": "^4.0.1", + "@tailwindcss/typography": "^0.5.9", "@tamagui/next-plugin": "1.11.1", "@types/d3-array": "^3.0.4", "@types/d3-time-format": "^4.0.0", "@types/node": "^18.11.11", "@types/react": "^18.0.33", "@types/react-dom": "^18.0.11", + "@types/tryghost__content-api": "^1.3.11", "autoprefixer": "^10.4.14", + "@status-im/eslint-config": "*", "postcss": "^8.4.21", + "rehype-parse": "^8.0.4", + "rehype-react": "^7.2.0", + "rehype-stringify": "^9.0.3", "tailwindcss": "^3.3.1", "tailwindcss-animate": "^1.0.5", - "typescript": "^5.0.3" + "typescript": "^5.0.3", + "unified": "^10.1.2" }, "engines": { "node": "^18.x" diff --git a/apps/website/public/images/social/facebook.svg b/apps/website/public/images/social/facebook.svg new file mode 100644 index 00000000..2a5125f9 --- /dev/null +++ b/apps/website/public/images/social/facebook.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + diff --git a/apps/website/public/images/social/reddit.svg b/apps/website/public/images/social/reddit.svg new file mode 100644 index 00000000..2d747800 --- /dev/null +++ b/apps/website/public/images/social/reddit.svg @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/apps/website/public/images/social/status.svg b/apps/website/public/images/social/status.svg new file mode 100644 index 00000000..dcb755fb --- /dev/null +++ b/apps/website/public/images/social/status.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/website/public/images/social/twitter.svg b/apps/website/public/images/social/twitter.svg new file mode 100644 index 00000000..ef0369d1 --- /dev/null +++ b/apps/website/public/images/social/twitter.svg @@ -0,0 +1,12 @@ + + + diff --git a/apps/website/src/components/link.tsx b/apps/website/src/components/link.tsx index 51701a61..d8dff052 100644 --- a/apps/website/src/components/link.tsx +++ b/apps/website/src/components/link.tsx @@ -1,8 +1,8 @@ import NextLink from 'next/link' -import type { ComponentProps } from 'react' +import type { ComponentPropsWithRef } from 'react' -export const Link = (props: ComponentProps) => { +export const Link = (props: ComponentPropsWithRef) => { const external = typeof props.href === 'string' ? props.href.startsWith('http') diff --git a/apps/website/src/components/logo.tsx b/apps/website/src/components/logo.tsx index 5dbb1b4c..b60c4839 100644 --- a/apps/website/src/components/logo.tsx +++ b/apps/website/src/components/logo.tsx @@ -16,7 +16,7 @@ export const Logo = (props: Props) => { const { pathname } = useRouter() return ( -
+
{match(pathname) .with( P.when(p => p.startsWith('/insights')), diff --git a/apps/website/src/components/nav-menu.tsx b/apps/website/src/components/nav-menu.tsx index 8053df8a..22fdc0f8 100644 --- a/apps/website/src/components/nav-menu.tsx +++ b/apps/website/src/components/nav-menu.tsx @@ -38,7 +38,7 @@ export const NavMenu = () => { data-visible={visible} className={cx([ 'fixed left-1/2 top-5 z-10 min-w-[746px] -translate-x-1/2 overflow-hidden', - 'bg-blur-neutral-80/80 border-neutral-80/5 rounded-2xl border backdrop-blur-md', + 'rounded-2xl border border-neutral-80/5 bg-blur-neutral-80/80 backdrop-blur-md', 'data-[visible=false]:pointer-events-none', 'opacity-0 transition-opacity data-[visible=true]:opacity-100', ])} @@ -58,7 +58,7 @@ export const NavMenu = () => { className={cx([ 'grid gap-3 pb-12 pl-[60px] pt-6', 'data-[state=open]:animate-in', - 'data-[state=closed]:animate-out fade-out-20', + 'fade-out-20 data-[state=closed]:animate-out', ])} > {links.map(link => { @@ -91,8 +91,8 @@ export const NavMenu = () => { diff --git a/apps/website/src/components/page-footer.tsx b/apps/website/src/components/page-footer.tsx index 7b8507f2..630465b4 100644 --- a/apps/website/src/components/page-footer.tsx +++ b/apps/website/src/components/page-footer.tsx @@ -118,7 +118,7 @@ const ActionCard = (props: ActionCardProps) => { const { title, description, action } = props return ( -
+
{title} diff --git a/apps/website/src/components/side-bar/side-bar.tsx b/apps/website/src/components/side-bar/side-bar.tsx index 754f2101..dfc8ec35 100644 --- a/apps/website/src/components/side-bar/side-bar.tsx +++ b/apps/website/src/components/side-bar/side-bar.tsx @@ -36,7 +36,7 @@ const SideBar = (props: Props) => { }, [defaultLabel]) return ( -
+