From e05c318035275cea6d7f38142eed95e6458f67f2 Mon Sep 17 00:00:00 2001
From: Pavel <14926950+prichodko@users.noreply.github.com>
Date: Wed, 3 May 2023 14:25:17 +0200
Subject: [PATCH] Add initial insights implementation (#388)
* add colors to tailwind config
* update reset.css
* add epics page
* add epic detail page
* add orphans page
* add repos page
* add missing @status-im/components exports
* update visx link
* support icons in
* update Tag in website
* emojiOnly -> iconOnly
* update icons scripts
* add missing dir to clean script
* enable eslint next config
* restructure website and add layouts
* move static data outside components
---
.eslintrc | 5 +-
apps/website/next.config.js | 11 +
apps/website/package.json | 1 +
apps/website/src/components/epic-overview.tsx | 790 ++++++++++++++++++
apps/website/src/components/table-issues.tsx | 85 ++
apps/website/src/layouts/insights-layout.tsx | 52 ++
apps/website/src/next.d.ts | 9 +
apps/website/{ => src}/pages/_app.tsx | 13 +-
apps/website/{ => src}/pages/_document.tsx | 2 +-
apps/website/src/pages/insights/[epic].tsx | 25 +
apps/website/src/pages/insights/index.tsx | 62 ++
apps/website/src/pages/insights/orphans.tsx | 22 +
apps/website/src/pages/insights/repos.tsx | 92 ++
apps/website/{ => src}/styles/app.css | 0
apps/website/{ => src}/styles/reset.css | 6 +-
apps/website/tailwind.config.js | 24 +-
apps/website/tsconfig.json | 4 +-
packages/components/package.json | 2 +-
packages/components/src/index.tsx | 2 +
packages/components/src/tag/index.tsx | 2 +-
packages/components/src/tag/tag.stories.tsx | 12 +-
packages/components/src/tag/tag.tsx | 36 +-
packages/icons/package.json | 7 +-
23 files changed, 1225 insertions(+), 39 deletions(-)
create mode 100644 apps/website/src/components/epic-overview.tsx
create mode 100644 apps/website/src/components/table-issues.tsx
create mode 100644 apps/website/src/layouts/insights-layout.tsx
create mode 100644 apps/website/src/next.d.ts
rename apps/website/{ => src}/pages/_app.tsx (55%)
rename apps/website/{ => src}/pages/_document.tsx (95%)
create mode 100644 apps/website/src/pages/insights/[epic].tsx
create mode 100644 apps/website/src/pages/insights/index.tsx
create mode 100644 apps/website/src/pages/insights/orphans.tsx
create mode 100644 apps/website/src/pages/insights/repos.tsx
rename apps/website/{ => src}/styles/app.css (100%)
rename apps/website/{ => src}/styles/reset.css (92%)
diff --git a/.eslintrc b/.eslintrc
index c8f5f29c..d6903d5c 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -46,10 +46,7 @@
{
// TODO: add https://github.com/francoismassart/eslint-plugin-tailwindcss
"files": ["./apps/website/"],
- "extends": [
- // "next"
- "next/core-web-vitals"
- ]
+ "extends": ["next", "next/core-web-vitals"]
// "settings": {
// "import/resolver": {
// "typescript": {
diff --git a/apps/website/next.config.js b/apps/website/next.config.js
index 835598aa..b6dd11cb 100644
--- a/apps/website/next.config.js
+++ b/apps/website/next.config.js
@@ -11,6 +11,7 @@ process.env.TAMAGUI_DISABLE_WARN_DYNAMIC_LOAD = '1'
/** @type {import('next').NextConfig} */
let config = {
+ // output: 'export',
reactStrictMode: true,
typescript: {
ignoreBuildErrors: true,
@@ -30,6 +31,16 @@ let config = {
legacyBrowsers: false,
// esmExternals: 'loose',
},
+
+ redirects: async () => {
+ return [
+ {
+ source: '/',
+ destination: '/insights',
+ permanent: false,
+ },
+ ]
+ },
}
const plugins = [
diff --git a/apps/website/package.json b/apps/website/package.json
index 29a84ac5..2a0588c0 100644
--- a/apps/website/package.json
+++ b/apps/website/package.json
@@ -17,6 +17,7 @@
"@status-im/components": "*",
"@status-im/icons": "*",
"@status-im/js": "*",
+ "@status-im/colors": "*",
"@tamagui/next-theme": "1.11.1",
"next": "13.2.4",
"react": "^18.2.0",
diff --git a/apps/website/src/components/epic-overview.tsx b/apps/website/src/components/epic-overview.tsx
new file mode 100644
index 00000000..59955691
--- /dev/null
+++ b/apps/website/src/components/epic-overview.tsx
@@ -0,0 +1,790 @@
+import { Tag, Text } from '@status-im/components'
+import { OpenIcon } from '@status-im/icons'
+
+type Props = {
+ title: string
+ description: string
+ fullscreen?: boolean
+}
+
+export const EpicOverview = (props: Props) => {
+ const { title, description, fullscreen } = props
+
+ return (
+
+
+
+ {title}
+
+
+
+
+ {description}
+
+
+
+
+
+
+
+
+
+ )
+}
+
+// USE https://airbnb.io/visx/areas
+const ChartPreview = () => (
+
+)
diff --git a/apps/website/src/components/table-issues.tsx b/apps/website/src/components/table-issues.tsx
new file mode 100644
index 00000000..1bfde8e7
--- /dev/null
+++ b/apps/website/src/components/table-issues.tsx
@@ -0,0 +1,85 @@
+import { Avatar, Button, Tag, Text } from '@status-im/components'
+import Link from 'next/link'
+
+const issues = [
+ {
+ id: 5154,
+ title: 'Add support for encrypted communities',
+ status: 'Open',
+ },
+ {
+ id: 5155,
+ title: 'Add support for encrypted communities',
+ status: 'Open',
+ },
+ {
+ id: 4,
+ title: 'Add support for encrypted communities',
+ status: 'Open',
+ },
+ {
+ id: 4324,
+ title: 'Add support for encrypted communities',
+ status: 'Open',
+ },
+ {
+ id: 876,
+ title: 'Add support for encrypted communities',
+ status: 'Open',
+ },
+]
+
+export const TableIssues = () => {
+ return (
+
+
+
+ 784 Open
+
+
+
+
+ {issues.map(issue => (
+
+
+
+ {issue.title}
+
+
+ #9667 • Opened 2 days ago by slaedjenic
+
+
+
+
+
+ ))}
+
+
+
+
+
+
+ )
+}
diff --git a/apps/website/src/layouts/insights-layout.tsx b/apps/website/src/layouts/insights-layout.tsx
new file mode 100644
index 00000000..e02fd459
--- /dev/null
+++ b/apps/website/src/layouts/insights-layout.tsx
@@ -0,0 +1,52 @@
+import { Button, Text } from '@status-im/components'
+import { LockedIcon, StatusIcon } from '@status-im/icons'
+import Link from 'next/link'
+import { useRouter } from 'next/router'
+
+import type { PageLayout } from 'next'
+import type { LinkProps } from 'next/link'
+
+export const InsightsLayout: PageLayout = page => {
+ return (
+ <>
+
+
+
+
+
+
+ }>
+ Log in
+
+
+
+
+ {page}
+ >
+ )
+}
+
+const NavLink = (props: LinkProps & { children: string }) => {
+ const { children, ...linkProps } = props
+
+ const { asPath } = useRouter()
+ const active = asPath === props.href
+
+ return (
+
+
+ {children}
+
+
+ )
+}
diff --git a/apps/website/src/next.d.ts b/apps/website/src/next.d.ts
new file mode 100644
index 00000000..62e1fc66
--- /dev/null
+++ b/apps/website/src/next.d.ts
@@ -0,0 +1,9 @@
+import type { NextPage } from 'next'
+
+declare module 'next' {
+ export type PageLayout = (page: React.ReactElement) => React.ReactNode
+
+ export type Page = NextPage
& {
+ getLayout?: (page: ReactElement) => ReactNode
+ }
+}
diff --git a/apps/website/pages/_app.tsx b/apps/website/src/pages/_app.tsx
similarity index 55%
rename from apps/website/pages/_app.tsx
rename to apps/website/src/pages/_app.tsx
index d8c0bf1d..f910f341 100644
--- a/apps/website/pages/_app.tsx
+++ b/apps/website/src/pages/_app.tsx
@@ -4,6 +4,7 @@ import '@/styles/reset.css'
import { Provider } from '@status-im/components'
import { Inter } from 'next/font/google'
+import type { Page, PageLayout } from 'next'
import type { AppProps } from 'next/app'
const inter = Inter({
@@ -12,12 +13,16 @@ const inter = Inter({
subsets: ['latin'],
})
-export default function App({ Component, pageProps }: AppProps) {
+type Props = AppProps & {
+ Component: Page
+}
+
+export default function App({ Component, pageProps }: Props) {
+ const getLayout: PageLayout = Component.getLayout || (page => page)
+
return (
)
}
diff --git a/apps/website/pages/_document.tsx b/apps/website/src/pages/_document.tsx
similarity index 95%
rename from apps/website/pages/_document.tsx
rename to apps/website/src/pages/_document.tsx
index d2cb1aec..df9bd6c0 100644
--- a/apps/website/pages/_document.tsx
+++ b/apps/website/src/pages/_document.tsx
@@ -3,7 +3,7 @@ import { Children } from 'react'
import NextDocument, { Head, Html, Main, NextScript } from 'next/document'
import { AppRegistry } from 'react-native'
-import Tamagui from '../tamagui.config'
+import Tamagui from '../../tamagui.config'
import type { DocumentContext } from 'next/document'
diff --git a/apps/website/src/pages/insights/[epic].tsx b/apps/website/src/pages/insights/[epic].tsx
new file mode 100644
index 00000000..68a822e4
--- /dev/null
+++ b/apps/website/src/pages/insights/[epic].tsx
@@ -0,0 +1,25 @@
+import { EpicOverview } from '@/components/epic-overview'
+import { TableIssues } from '@/components/table-issues'
+import { InsightsLayout } from '@/layouts/insights-layout'
+
+import type { Page } from 'next'
+
+const InsightsDetailPage: Page = () => {
+ return (
+ <>
+
+
+
+
+
+ >
+ )
+}
+
+InsightsDetailPage.getLayout = InsightsLayout
+
+export default InsightsDetailPage
diff --git a/apps/website/src/pages/insights/index.tsx b/apps/website/src/pages/insights/index.tsx
new file mode 100644
index 00000000..4a47fdea
--- /dev/null
+++ b/apps/website/src/pages/insights/index.tsx
@@ -0,0 +1,62 @@
+import { IconButton, Shadow, Tag, Text } from '@status-im/components'
+import {
+ DoneIcon,
+ NotStartedIcon,
+ OpenIcon,
+ SearchIcon,
+ SortIcon,
+} from '@status-im/icons'
+
+import { EpicOverview } from '@/components/epic-overview'
+import { InsightsLayout } from '@/layouts/insights-layout'
+
+import type { Page } from 'next'
+
+const epics = [
+ {
+ id: 1,
+ title: 'Communities protocol',
+ description: 'Support Encrypted Communities',
+ },
+ {
+ id: 5155,
+ title: 'Keycard',
+ description:
+ 'Detecting keycard reader removal for the beginning of each flow',
+ },
+]
+
+const InsightsPage: Page = () => {
+ return (
+
+
+ Epics
+
+
+
+
+
+
+
+
+
+
+ } />
+ } />
+
+
+
+
+ {epics.map(epic => (
+
+
+
+ ))}
+
+
+ )
+}
+
+InsightsPage.getLayout = InsightsLayout
+
+export default InsightsPage
diff --git a/apps/website/src/pages/insights/orphans.tsx b/apps/website/src/pages/insights/orphans.tsx
new file mode 100644
index 00000000..57d5b0d7
--- /dev/null
+++ b/apps/website/src/pages/insights/orphans.tsx
@@ -0,0 +1,22 @@
+import { Text } from '@status-im/components'
+
+import { TableIssues } from '@/components/table-issues'
+import { InsightsLayout } from '@/layouts/insights-layout'
+
+import type { Page } from 'next'
+
+const OrphansPage: Page = () => {
+ return (
+
+ )
+}
+
+OrphansPage.getLayout = InsightsLayout
+
+export default OrphansPage
diff --git a/apps/website/src/pages/insights/repos.tsx b/apps/website/src/pages/insights/repos.tsx
new file mode 100644
index 00000000..eb320f58
--- /dev/null
+++ b/apps/website/src/pages/insights/repos.tsx
@@ -0,0 +1,92 @@
+import { Text } from '@status-im/components'
+import Link from 'next/link'
+
+import { InsightsLayout } from '@/layouts/insights-layout'
+
+import type { Page } from 'next'
+
+const repos = [
+ {
+ name: 'status-web',
+ description: 'a free (libre) open source, mobile OS for Ethereum.',
+ issues: 10,
+ stars: 5,
+ },
+ {
+ name: 'status-mobile',
+ description: 'a free (libre) open source, mobile OS for Ethereum.',
+ issues: 10,
+ stars: 5,
+ },
+ {
+ name: 'status-desktop',
+ description: 'a free (libre) open source, mobile OS for Ethereum.',
+ issues: 10,
+ stars: 5,
+ },
+ {
+ name: 'status-go',
+ description: 'a free (libre) open source, mobile OS for Ethereum.',
+ issues: 10,
+ stars: 5,
+ },
+ {
+ name: 'nimbus-eth2',
+ description: 'a free (libre) open source, mobile OS for Ethereum.',
+ issues: 10,
+ stars: 5,
+ },
+ {
+ name: 'help.status.im',
+ description: 'help.status.im',
+ issues: 10,
+ stars: 5,
+ },
+]
+
+const ReposPage: Page = () => {
+ return (
+ <>
+
+
+ Repos
+
+
+
+
+ {repos.map(repo => (
+
+
+ {repo.name}
+
+
+ {repo.description}
+
+
+
+
+ Public
+
+
+ 42 Issues
+
+
+ 32
+
+
+
+ ))}
+
+ >
+ )
+}
+
+ReposPage.getLayout = InsightsLayout
+
+export default ReposPage
diff --git a/apps/website/styles/app.css b/apps/website/src/styles/app.css
similarity index 100%
rename from apps/website/styles/app.css
rename to apps/website/src/styles/app.css
diff --git a/apps/website/styles/reset.css b/apps/website/src/styles/reset.css
similarity index 92%
rename from apps/website/styles/reset.css
rename to apps/website/src/styles/reset.css
index a6ff38e8..a9bb35ba 100644
--- a/apps/website/styles/reset.css
+++ b/apps/website/src/styles/reset.css
@@ -8,7 +8,7 @@
}
:root {
- font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-family: var(--font-sans);
font-size: 16px;
line-height: 24px;
font-weight: 400;
@@ -36,9 +36,9 @@
*/
html,
body {
- height: 100vh;
width: 100vw;
- overflow: hidden;
+ min-height: 100%;
+ /* overflow: hidden; */
overscroll-behavior-y: none; /* not working on Safari */
}
/*
diff --git a/apps/website/tailwind.config.js b/apps/website/tailwind.config.js
index f11b3412..41cb12f4 100644
--- a/apps/website/tailwind.config.js
+++ b/apps/website/tailwind.config.js
@@ -1,16 +1,28 @@
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const colors = require('@status-im/colors')
+
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
+ './src/**/*.{js,ts,jsx,tsx,mdx}',
// './app/**/*.{js,ts,jsx,tsx,mdx}',
- './pages/**/*.{js,ts,jsx,tsx,mdx}',
- './components/**/*.{js,ts,jsx,tsx,mdx}',
-
- // todo: move all to `src` directory
- // // Or if using `src` directory:
- // './src/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
+ fontFamily: {
+ sans: ['var(--font-inter)'],
+ },
+ colors,
+
+ // use from @status-im/components
+ fontSize: {},
+ fontWeight: {
+ // regular: '400',
+ // medium: '500',
+ // semibold: '600',
+ },
+
extend: {},
},
+
plugins: [],
}
diff --git a/apps/website/tsconfig.json b/apps/website/tsconfig.json
index b4b81477..78b35344 100644
--- a/apps/website/tsconfig.json
+++ b/apps/website/tsconfig.json
@@ -10,7 +10,7 @@
"baseUrl": ".",
"paths": {
"react-native": ["react-native-web"],
- "@/*": ["./*"]
+ "@/*": ["./src/*"]
// "@status-im/*": ["./node_modules/@status-im/*"]
// "@status-im/js": ["./node_modules/@status-im/js/packages/status-js"],
// "@status-im/components": [
@@ -19,5 +19,5 @@
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
- "exclude": ["node_modules", "next.config.js"]
+ "exclude": ["node_modules", "next.config.js", "tailwind.config.js"]
}
diff --git a/packages/components/package.json b/packages/components/package.json
index a91c36b0..e035fcc6 100644
--- a/packages/components/package.json
+++ b/packages/components/package.json
@@ -24,7 +24,7 @@
"storybook": "node ./scripts/storybook.js",
"storybook:dev": "TAMAGUI_TARGET='web' storybook dev -p 3001",
"storybook:build": "TAMAGUI_TARGET='web' storybook build",
- "clean": "rimraf node_modules dist .turbo storybook-static"
+ "clean": "rimraf node_modules dist .turbo storybook-static .tamagui"
},
"peerDependencies": {
"react": "^18.2.0"
diff --git a/packages/components/src/index.tsx b/packages/components/src/index.tsx
index e7552ed6..30978b41 100644
--- a/packages/components/src/index.tsx
+++ b/packages/components/src/index.tsx
@@ -13,7 +13,9 @@ export * from './input'
export * from './messages'
export * from './pinned-message'
export * from './provider'
+export * from './shadow'
export * from './skeleton'
+export * from './tag'
export * from './text'
export * from './toast'
export * from './user-list'
diff --git a/packages/components/src/tag/index.tsx b/packages/components/src/tag/index.tsx
index 9d018728..fde6de86 100644
--- a/packages/components/src/tag/index.tsx
+++ b/packages/components/src/tag/index.tsx
@@ -1 +1 @@
-export { Tag } from './tag'
+export { Tag, type TagProps } from './tag'
diff --git a/packages/components/src/tag/tag.stories.tsx b/packages/components/src/tag/tag.stories.tsx
index 17dc8761..ad81d7a4 100644
--- a/packages/components/src/tag/tag.stories.tsx
+++ b/packages/components/src/tag/tag.stories.tsx
@@ -22,13 +22,13 @@ export const Default: Story = {
return (
-
-
-
-
+
+
+
+
-
-
+
+
diff --git a/packages/components/src/tag/tag.tsx b/packages/components/src/tag/tag.tsx
index c01d04ad..a90f613b 100644
--- a/packages/components/src/tag/tag.tsx
+++ b/packages/components/src/tag/tag.tsx
@@ -1,12 +1,16 @@
+import { createElement } from 'react'
+
import { Stack, styled } from '@tamagui/core'
import { Text } from '../text'
import type { TextProps } from '../text'
+import type { IconProps } from '@status-im/icons'
+import type { ComponentType } from 'react'
type Props = {
size: 32 | 24
- emoji?: string
+ icon?: string | ComponentType
label?: string
selected?: boolean
disabled?: boolean
@@ -17,17 +21,34 @@ const textSizes: Record, TextProps['size']> = {
'24': 13,
}
+const iconSizes: Record, IconProps['size']> = {
+ '32': 20,
+ '24': 12,
+}
+
const Tag = (props: Props) => {
- const { size, emoji, label, selected, disabled } = props
+ const { size, icon, label, selected, disabled } = props
+
+ const renderIcon = () => {
+ if (!icon) {
+ return null
+ }
+
+ if (typeof icon === 'string') {
+ return {icon}
+ }
+
+ return createElement(icon, { size: iconSizes[size] })
+ }
return (
- {emoji && {emoji}}
+ {renderIcon()}
{label && (
{label}
@@ -37,6 +58,9 @@ const Tag = (props: Props) => {
)
}
+export { Tag }
+export type { Props as TagProps }
+
const Base = styled(Stack, {
display: 'flex',
flexDirection: 'row',
@@ -76,12 +100,10 @@ const Base = styled(Stack, {
},
},
- emojiOnly: {
+ iconOnly: {
true: {
paddingHorizontal: 0,
},
},
},
})
-
-export { Tag }
diff --git a/packages/icons/package.json b/packages/icons/package.json
index 44edfad6..371725fc 100644
--- a/packages/icons/package.json
+++ b/packages/icons/package.json
@@ -21,13 +21,12 @@
}
},
"scripts": {
- "sync": " vite-node scripts/sync.ts",
+ "sync": "vite-node scripts/sync.ts && yarn generate",
+ "generate": "rimraf src && svgr svg --out-dir src",
"dev": "vite build --watch --mode development",
- "build:icons": "rimraf src && svgr svg --out-dir src",
- "build:types": "tsc --noEmit false --emitDeclarationOnly",
- "prebuild": "yarn build:icons",
"build": "vite build",
"postbuild": "yarn build:types",
+ "build:types": "tsc --noEmit false --emitDeclarationOnly",
"#test": "vitest",
"typecheck": "tsc",
"lint": "eslint 'src/**/*.{ts,tsx}'",