From 183564aed810ae94eed3d04ba879e104529178b2 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sat, 1 May 2021 15:13:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Article=20=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 12 +-- apollo.config.js | 2 +- package-lock.json | 136 +++++++++++++++++----------- package.json | 4 +- src/articles/article-editor.tsx | 116 +++++++++++++++++++----- src/articles/articles-index.tsx | 82 +++++++++++++++++ src/articles/articles.constants.tsx | 26 ++++++ src/articles/index.ts | 3 + src/articles/index.tsx | 56 ------------ src/commons/editor/vditor.tsx | 15 ++- src/index.tsx | 31 ++++--- src/routes.tsx | 73 +++++++++------ 12 files changed, 367 insertions(+), 189 deletions(-) create mode 100644 src/articles/articles-index.tsx create mode 100644 src/articles/articles.constants.tsx create mode 100644 src/articles/index.ts delete mode 100644 src/articles/index.tsx diff --git a/.vscode/launch.json b/.vscode/launch.json index de25478..b852e41 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,19 +5,13 @@ "version": "0.2.0", "configurations": [ { + "name": "chrome", "type": "chrome", "request": "launch", - "name": "Launch Chrome against blog.localhost", - "url": "http://localhost:8090/", - "webRoot": "${workspaceFolder}" - }, - { - "name": "Launch blog.localhost", - "type": "firefox", - "request": "launch", "reAttach": true, "url": "http://blog.localhost/", - "webRoot": "${workspaceFolder}" + "webRoot": "${workspaceFolder}", + "userDataDir": "/Users/ivan/Projects/.chrome" } ] } diff --git a/apollo.config.js b/apollo.config.js index 2ac0681..d71335b 100644 --- a/apollo.config.js +++ b/apollo.config.js @@ -2,7 +2,7 @@ module.exports = { client: { service: { name: 'blog-be', - url: 'http://localhost:7132/graphql' + url: 'http://api.blog.localhost/graphql' } } }; diff --git a/package-lock.json b/package-lock.json index e15d1de..b2eb41c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@hickory/browser": "^2.1.0", "@material-ui/core": "^4.11.3", "@material-ui/icons": "^4.11.2", + "@material-ui/lab": "*", "@material-ui/pickers": "^3.3.10", "@testing-library/jest-dom": "^5.11.10", "@testing-library/react": "^11.2.6", @@ -28,6 +29,7 @@ "formik-material-ui": "^3.0.1", "formik-material-ui-pickers": "^0.0.12", "graphql": "^15.5.0", + "ramda": "^0.27.1", "react": "^17.0.2", "react-dom": "^17.0.2", "react-scripts": "4.0.3", @@ -44,7 +46,7 @@ "@graphql-codegen/typescript-react-apollo": "2.2.3", "@types/date-fns": "^2.6.0", "@types/graphql": "^14.5.0", - "@types/react-router-dom": "^5.1.7", + "@types/ramda": "^0.27.40", "@types/sass": "^1.16.0", "@types/yup": "^0.29.11", "sass": "^1.32.11" @@ -3148,6 +3150,32 @@ "node": ">=8.0.0" } }, + "node_modules/@material-ui/lab": { + "version": "4.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.58.tgz", + "integrity": "sha512-GKHlJqLxUeHH3L3dGQ48ZavYrqGOTXkFkiEiuYMAnAvXAZP4rhMIqeHOPXSUQan4Bd8QnafDcpovOSLnadDmKw==", + "dependencies": { + "@babel/runtime": "^7.4.4", + "@material-ui/utils": "^4.11.2", + "clsx": "^1.0.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@material-ui/core": "^4.9.10", + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@material-ui/pickers": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/@material-ui/pickers/-/pickers-3.3.10.tgz", @@ -3877,12 +3905,6 @@ "graphql": "*" } }, - "node_modules/@types/history": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz", - "integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==", - "dev": true - }, "node_modules/@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -3998,6 +4020,15 @@ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, + "node_modules/@types/ramda": { + "version": "0.27.40", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.27.40.tgz", + "integrity": "sha512-V99ZfTH2tqVYdLDAlgh2uT+N074HPgqnAsMjALKSBqogYd0HbuuGMqNukJ6fk9Ml/Htaus76fsc4Yh3p7q1VdQ==", + "dev": true, + "dependencies": { + "ts-toolbelt": "^6.15.1" + } + }, "node_modules/@types/react": { "version": "17.0.3", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.3.tgz", @@ -4016,27 +4047,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-router": { - "version": "5.1.13", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.13.tgz", - "integrity": "sha512-ZIuaO9Yrln54X6elg8q2Ivp6iK6p4syPsefEYAhRDAoqNh48C8VYUmB9RkXjKSQAJSJV0mbIFCX7I4vZDcHrjg==", - "dev": true, - "dependencies": { - "@types/history": "*", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.7.tgz", - "integrity": "sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg==", - "dev": true, - "dependencies": { - "@types/history": "*", - "@types/react": "*", - "@types/react-router": "*" - } - }, "node_modules/@types/react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", @@ -18148,6 +18158,11 @@ "performance-now": "^2.1.0" } }, + "node_modules/ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -21463,6 +21478,12 @@ "node": ">=6" } }, + "node_modules/ts-toolbelt": { + "version": "6.15.5", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz", + "integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==", + "dev": true + }, "node_modules/tsconfig-paths": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", @@ -26787,6 +26808,18 @@ "@babel/runtime": "^7.4.4" } }, + "@material-ui/lab": { + "version": "4.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.58.tgz", + "integrity": "sha512-GKHlJqLxUeHH3L3dGQ48ZavYrqGOTXkFkiEiuYMAnAvXAZP4rhMIqeHOPXSUQan4Bd8QnafDcpovOSLnadDmKw==", + "requires": { + "@babel/runtime": "^7.4.4", + "@material-ui/utils": "^4.11.2", + "clsx": "^1.0.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0" + } + }, "@material-ui/pickers": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/@material-ui/pickers/-/pickers-3.3.10.tgz", @@ -27380,12 +27413,6 @@ "graphql": "*" } }, - "@types/history": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz", - "integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==", - "dev": true - }, "@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -27501,6 +27528,15 @@ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, + "@types/ramda": { + "version": "0.27.40", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.27.40.tgz", + "integrity": "sha512-V99ZfTH2tqVYdLDAlgh2uT+N074HPgqnAsMjALKSBqogYd0HbuuGMqNukJ6fk9Ml/Htaus76fsc4Yh3p7q1VdQ==", + "dev": true, + "requires": { + "ts-toolbelt": "^6.15.1" + } + }, "@types/react": { "version": "17.0.3", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.3.tgz", @@ -27519,27 +27555,6 @@ "@types/react": "*" } }, - "@types/react-router": { - "version": "5.1.13", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.13.tgz", - "integrity": "sha512-ZIuaO9Yrln54X6elg8q2Ivp6iK6p4syPsefEYAhRDAoqNh48C8VYUmB9RkXjKSQAJSJV0mbIFCX7I4vZDcHrjg==", - "dev": true, - "requires": { - "@types/history": "*", - "@types/react": "*" - } - }, - "@types/react-router-dom": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.7.tgz", - "integrity": "sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg==", - "dev": true, - "requires": { - "@types/history": "*", - "@types/react": "*", - "@types/react-router": "*" - } - }, "@types/react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", @@ -39296,6 +39311,11 @@ "performance-now": "^2.1.0" } }, + "ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -42088,6 +42108,12 @@ "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==" }, + "ts-toolbelt": { + "version": "6.15.5", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz", + "integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==", + "dev": true + }, "tsconfig-paths": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", diff --git a/package.json b/package.json index 8c74332..27c5346 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@hickory/browser": "^2.1.0", "@material-ui/core": "^4.11.3", "@material-ui/icons": "^4.11.2", + "@material-ui/lab": "*", "@material-ui/pickers": "^3.3.10", "@testing-library/jest-dom": "^5.11.10", "@testing-library/react": "^11.2.6", @@ -24,6 +25,7 @@ "formik-material-ui": "^3.0.1", "formik-material-ui-pickers": "^0.0.12", "graphql": "^15.5.0", + "ramda": "^0.27.1", "react": "^17.0.2", "react-dom": "^17.0.2", "react-scripts": "4.0.3", @@ -65,7 +67,7 @@ "@graphql-codegen/typescript-react-apollo": "2.2.3", "@types/date-fns": "^2.6.0", "@types/graphql": "^14.5.0", - "@types/react-router-dom": "^5.1.7", + "@types/ramda": "^0.27.40", "@types/sass": "^1.16.0", "@types/yup": "^0.29.11", "sass": "^1.32.11" diff --git a/src/articles/article-editor.tsx b/src/articles/article-editor.tsx index 55751b7..cf4ec97 100644 --- a/src/articles/article-editor.tsx +++ b/src/articles/article-editor.tsx @@ -9,20 +9,32 @@ import { Field, Form, Formik, FormikHelpers } from "formik"; import { FC } from "react"; import { Editor } from "../commons/editor/vditor"; import * as Yup from "yup"; -import { - CreateArticleInput, - UpdateArticleInput, -} from "../generated/graphql"; -import { DateTimePicker } from 'formik-material-ui-pickers'; -import { gql, useMutation } from '@apollo/client'; +import { Article, CreateArticleInput, UpdateArticleInput } from "../generated/graphql"; +import { DateTimePicker } from "formik-material-ui-pickers"; +import { gql, useMutation } from "@apollo/client"; +import { useRouter } from "@curi/react-universal"; const CREATE_ARTICLE = gql` -mutation createArticle($input: CreateArticleInput!) { - createArticle(input: $input) { - id, + mutation createArticle($createArticleInput: CreateArticleInput!) { + createArticle(createArticleInput: $createArticleInput) { + id + title + content + publishedAt + } } -} -` +`; + +const UPDATE_ARTICLE = gql` + mutation updateArticle($updateArticleInput: UpdateArticleInput!) { + updateArticle(updateArticleInput: $updateArticleInput) { + id + title + content + publishedAt + } + } +`; const useStyles = makeStyles((theme) => createStyles({ @@ -47,32 +59,90 @@ export const ArticleEditor: FC = ({ article }) => { content: Yup.string() .max(65535, "文章内容不得超过 65535 个字符") .required("文章内容不得为空"), - publishedAt: Yup.date() + publishedAt: Yup.date(), }); + const router = useRouter(); - const [createArticle] = useMutation(CREATE_ARTICLE); + const [createArticle] = useMutation<{createArticle: Article} ,{ + createArticleInput: CreateArticleInput; + }>(CREATE_ARTICLE, { + update(cache, { data }) { + cache.modify({ + fields: { + articles(existingArticles = []) { + const newArticleRef = cache.writeFragment({ + data: data!.createArticle, + fragment: gql` + fragment NewArticle on Article { + id + title + content + publishedAt + } + `, + }); + return [newArticleRef, ...existingArticles]; + }, + }, + }); + }, + }); + const [updateArticle] = useMutation<{ + updateArticleInput: UpdateArticleInput; + }>(UPDATE_ARTICLE); const SubmitForm = ( values: Values, { setSubmitting }: FormikHelpers ) => { - if ('id' in article!) { - console.log('update', article) - } else { - const title = /# (.+)$/.exec(values.content ?? '')?.[1]; + if ("id" in article!) { + const title = /# (.+)$/m.exec(values.content ?? "")?.[1]; if (!title) { - console.log('no title') + console.log("no title"); + setSubmitting(false); + return; + } + updateArticle({ + variables: { + updateArticleInput: { + ...values, + title, + }, + }, + }) + .then(() => { + router.navigate({ + url: router.url({ name: "articles" }), + method: "replace", + }); + }) + .finally(() => { + setSubmitting(false); + }); + } else { + const title = /# (.+)$/m.exec(values.content ?? "")?.[1]; + if (!title) { + console.log("no title"); setSubmitting(false); return; } createArticle({ variables: { - ...values, - title, + createArticleInput: { + ...values as CreateArticleInput, + title, + }, }, - }).finally(() => { - setSubmitting(false); - }); + }) + .then(() => { + router.navigate({ + url: router.url({ name: "articles" }), + method: "replace", + }); + }) + .finally(() => { + setSubmitting(false); + }); } setSubmitting(false); }; diff --git a/src/articles/articles-index.tsx b/src/articles/articles-index.tsx new file mode 100644 index 0000000..75ea7da --- /dev/null +++ b/src/articles/articles-index.tsx @@ -0,0 +1,82 @@ +import { useMutation, useQuery } from "@apollo/client"; +import { + IconButton, + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, +} from "@material-ui/core"; +import React, { FC } from "react"; +import { Article } from "../generated/graphql"; +import EditIcon from "@material-ui/icons/Edit"; +import { useRouter } from "@curi/react-dom"; +import { ARTICLES, REMOVE_ARTICLE } from './articles.constants'; +import { Delete } from '@material-ui/icons'; + +export const ArticleIndex: FC = () => { + const { data } = useQuery<{ + articles: Article[]; + }>(ARTICLES, {}); + + const [removeArticle] = useMutation(REMOVE_ARTICLE); + + const router = useRouter(); + + return ( +
+ + + + + Article Title + Published At + Views + Comments + Actions + + + + {data?.articles.map((article) => ( + + + {article.title} + + {article.publishedAt} + -- + -- + + + router.navigate({ + url: router.url({ + name: "modify-article", + params: article, + }), + }) + } + > + + + + removeArticle({ + variables: article, + }) + } + > + + + + + ))} + +
+
+
+ ); +}; diff --git a/src/articles/articles.constants.tsx b/src/articles/articles.constants.tsx new file mode 100644 index 0000000..80b838a --- /dev/null +++ b/src/articles/articles.constants.tsx @@ -0,0 +1,26 @@ +import { gql } from "@apollo/client"; + +export const ARTICLE = gql` + query Article($id: String!) { + article(id: $id) { + id + title + content + publishedAt + } + } +`; +export const ARTICLES = gql` + query Articles { + articles { + id + title + publishedAt + } + } +`; +export const REMOVE_ARTICLE = gql` + mutation RemoveArticle($id: String!) { + removeArticle(id: $id) + } +`; \ No newline at end of file diff --git a/src/articles/index.ts b/src/articles/index.ts new file mode 100644 index 0000000..31755af --- /dev/null +++ b/src/articles/index.ts @@ -0,0 +1,3 @@ +export * from './article-editor'; +export * from './articles-index'; +export * from './articles.constants' \ No newline at end of file diff --git a/src/articles/index.tsx b/src/articles/index.tsx deleted file mode 100644 index dd2431e..0000000 --- a/src/articles/index.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { gql, useQuery } from "@apollo/client"; -import { - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, -} from "@material-ui/core"; -import React, { FC } from "react"; -import { Article } from '../generated/graphql'; - -const articles = gql` -query Articles { - articles { - id - title - publishedAt - } -}`; - -export const ArticleIndex: FC = () => { - const { data } = useQuery<{ - articles: Article[]; - }>(articles, {}); - - return ( -
- - - - - Article Title - Published At - Views - Comments - - - - {data?.articles.map((article) => ( - - - {article.title} - - {article.publishedAt} - -- - -- - - ))} - -
-
-
- ); -}; diff --git a/src/commons/editor/vditor.tsx b/src/commons/editor/vditor.tsx index 73e89dc..07807fc 100644 --- a/src/commons/editor/vditor.tsx +++ b/src/commons/editor/vditor.tsx @@ -1,4 +1,4 @@ -import { FormControl, FormHelperText, FormLabel } from '@material-ui/core'; +import { createStyles, FormControl, FormHelperText, FormLabel, makeStyles } from '@material-ui/core'; import { FieldHookConfig, useField } from 'formik'; import React, { FC, useEffect, useRef, useState } from 'react'; import Vditor from 'vditor'; @@ -9,6 +9,14 @@ type Props = (FieldHookConfig) & { className?: string; }; +const useStyles = makeStyles((theme) => + createStyles({ + formControl: { + width: '100%', + }, + }) +); + export const Editor: FC = ({ label, className, ...props }) => { const [field, meta, helpers] = useField(props); const editor = useRef(null); @@ -25,6 +33,7 @@ export const Editor: FC = ({ label, className, ...props }) => { fullscreen: { index: 1500, }, + value: meta.initialValue, input: (val) => helpers.setValue(val), blur: () => helpers.setTouched(true), }); @@ -33,8 +42,10 @@ export const Editor: FC = ({ label, className, ...props }) => { instance?.destroy(); }; }, []); + + const classes = useStyles(); return ( - + {label}
{meta.error && {meta.error}} diff --git a/src/index.tsx b/src/index.tsx index 717a1f0..c83e9a2 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,25 +1,26 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import './index.css'; +import React from "react"; +import ReactDOM from "react-dom"; +import "./index.css"; import "fontsource-roboto"; -import App from './App'; -import reportWebVitals from './reportWebVitals'; -import { client } from './commons/graphql/client'; -import { ApolloProvider } from '@apollo/client'; -import { MuiPickersUtilsProvider } from '@material-ui/pickers'; +import App from "./App"; +import reportWebVitals from "./reportWebVitals"; +import { client } from "./commons/graphql/client"; +import { ApolloProvider } from "@apollo/client"; +import { MuiPickersUtilsProvider } from "@material-ui/pickers"; import DateFnsUtils from "@date-io/date-fns"; import zhLocale from "date-fns/locale/zh-CN"; -import { createRouterComponent } from '@curi/react-dom'; -import { createRouter, announce } from '@curi/router'; -import { browser } from '@hickory/browser'; -import routes from './routes'; +import { createRouterComponent } from "@curi/react-dom"; +import { createRouter, announce } from "@curi/router"; +import { browser } from "@hickory/browser"; +import routes from "./routes"; const router = createRouter(browser, routes, { sideEffects: [ announce(({ response }) => { return `Navigated to ${response.location.pathname}`; - }) - ] + }), + ], + external: { client } }); const Router = createRouterComponent(router); @@ -36,7 +37,7 @@ router.once(() => { , document.getElementById("root") ); -}) +}); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) diff --git a/src/routes.tsx b/src/routes.tsx index f338480..a1955bc 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -1,50 +1,69 @@ -import { prepareRoutes } from '@curi/router' +import { ApolloClient } from "@apollo/client"; +import { prepareRoutes } from "@curi/router"; +import { omit } from 'ramda'; +import { ARTICLE } from "./articles"; +import { Article } from './generated/graphql'; export default prepareRoutes([ { - name: 'dashboard', - path: '', + name: "dashboard", + path: "", respond() { - return { body: () => (
DashBoard
) } - } + return { body: () =>
DashBoard
}; + }, }, { - name: 'create-article', - path: 'articles/create', + name: "create-article", + path: "articles/create", resolve() { - const body = import(/* webpackChunkName: "create-article" */ './articles/article-editor').then(m => m.ArticleEditor); + const body = import( + /* webpackChunkName: "article-editor" */ "./articles" + ).then((m) => m.ArticleEditor); return body; }, respond({ resolved }) { - return { body: resolved } - } + return { body: resolved }; + }, }, { - name: 'modify-article', - path: 'articles/:id', - resolve() { - return import(/* webpackChunkName: "modify-article" */ './articles/article-editor').then(m => m.ArticleEditor); + name: "modify-article", + path: "articles/:id", + async resolve(matched, { client }: { client: ApolloClient }) { + const [ArticleEditor, result] = await Promise.all([ + import(/* webpackChunkName: "article-editor" */ "./articles").then( + (m) => m.ArticleEditor + ), + client.query<{article: Article}, { id: string }>({ + query: ARTICLE, + variables: { id: matched!.params.id }, + }), + ]); + console.log(ArticleEditor, result); + return () => ( + + ); }, respond({ resolved }) { - const ModifyArticle = () => resolved(); - return { body: } - } + return { body: resolved }; + }, }, { - name: 'articles', - path: 'articles', + name: "articles", + path: "articles", resolve() { - return import(/* webpackChunkName: "articles" */ './articles/index').then(m => m.ArticleIndex); + return import(/* webpackChunkName: "articles" */ "./articles").then( + (m) => m.ArticleIndex + ); }, respond({ resolved }) { - return { body: resolved } - } + return { body: resolved }; + }, }, { - name: 'tags', - path: 'tags', + name: "tags", + path: "tags", respond() { - return { body: () => (
Tags
) } - } + return { body: () =>
Tags
}; + }, }, -]) \ No newline at end of file +]);