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 ( + <> +
+ + + + +
+ +
+
+ +
{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 (

- - - + {getLayout()}
) } 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 ( +
+ + Orphans + + + +
+ ) +} + +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}'",