Skip to content

Commit

Permalink
Add react query todo app sample (#1810)
Browse files Browse the repository at this point in the history
* add react query todo app

* add react query todo app

* add filter, solve delay issue when adding or toggling

* remove redux, update READ.ME
  • Loading branch information
zenz34 authored and jchip committed Feb 5, 2021
1 parent 89da6fb commit 3dab9cd
Show file tree
Hide file tree
Showing 22 changed files with 7,619 additions and 0 deletions.
4 changes: 4 additions & 0 deletions samples/subapp2-react-query-todoapp/.browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Browsers that we support
last 2 versions
ie >= 11
> 5%
44 changes: 44 additions & 0 deletions samples/subapp2-react-query-todoapp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
node_modules

### OSX ###
.DS_Store
.AppleDouble
.LSOverride

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### Node ###
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Coverage directory used by tools like istanbul
coverage

.tmp
.nyc_output
config/assets.json
.isomorphic*
lib
23 changes: 23 additions & 0 deletions samples/subapp2-react-query-todoapp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# my-x-app

Welcome to React Query Todo application using Electrode X.

## Development

```
npm install
```

- Then to develop your app, do

```
npm run dev
```

- Once App is running, point browser to <http://localhost:3000>

Contribute to the [Electrode Platform](https://github.com/electrode-io/electrode/blob/master/CONTRIBUTING.md).

## Resources

- Check Electrode docs at <https://www.electrode.io/electrode/>
6 changes: 6 additions & 0 deletions samples/subapp2-react-query-todoapp/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"use strict";

const { babelPresetFile } = require("@xarc/app-dev");
module.exports = {
presets: [babelPresetFile]
};
56 changes: 56 additions & 0 deletions samples/subapp2-react-query-todoapp/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "my-x-app",
"version": "0.0.1",
"description": "Web application using Electrode X",
"homepage": "",
"scripts": {
"dev": "clap -q dev",
"test": "clap check",
"build": "clap build",
"start": "node lib/server"
},
"author": {
"name": "",
"email": "",
"url": ""
},
"contributors": [],
"main": "lib/server/index.js",
"keywords": [
"electrode",
"web"
],
"repository": {
"type": "git",
"url": ""
},
"license": "UNLICENSED",
"engines": {
"node": ">= 10",
"npm": ">= 6"
},
"dependencies": {
"@babel/runtime": "^7.12.5",
"@xarc/app": "^8.2.4",
"@xarc/fastify-server": "^2.0.0",
"@xarc/react": "^0.1.3",
"@xarc/react-query": "^0.1.0"
},
"devDependencies": {
"@types/node": "^14.14.6",
"@xarc/app-dev": "^8.2.4",
"classnames": "^2.2.6",
"ts-node": "^9.0.0",
"typescript": "^4.0.3"
},
"fyn": {
"dependencies": {
"@xarc/app": "../../packages/xarc-app",
"@xarc/react": "../../packages/xarc-react",
"@xarc/react-query": "../../packages/xarc-react-query"
},
"devDependencies": {
"@xarc/app-dev": "../../packages/xarc-app-dev"
}
}
}
8 changes: 8 additions & 0 deletions samples/subapp2-react-query-todoapp/src/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { declareSubApp, xarcV2 } from "@xarc/react";

export const Todo = declareSubApp({
name: "todo",
getModule: () => import("./todo")
});

xarcV2.debug("app.tsx");
30 changes: 30 additions & 0 deletions samples/subapp2-react-query-todoapp/src/server/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use strict";

/**
* A simple configuration to setup fastify to serve routes for the
* Electrode X webapp.
*
* To support config composition base on environment, checkout these:
*
* 1. https://www.npmjs.com/package/electrode-confippet
* 2. https://www.npmjs.com/package/config
*
*/
export const config = {
connection: {
host: process.env.HOST || "localhost",
// Allow Electrode X to control app's listening port during dev
// to serve both static assets and app under a unified proxy port
port: parseInt(process.env.APP_SERVER_PORT || process.env.PORT || "3000")
},
plugins: {
/**
* Register the dev support plugin
*/
"@xarc/app-dev": {
priority: -1,
enable: process.env.WEBPACK_DEV === "true"
}
},
deferStart: true
};
21 changes: 21 additions & 0 deletions samples/subapp2-react-query-todoapp/src/server/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { loadRuntimeSupport } from "@xarc/app";
import electrodeServer from "@xarc/fastify-server";
import { config } from "./config";

async function start() {
await loadRuntimeSupport({
isomorphicCdnOptions: {
prodOnly: true
}
});

const server = await electrodeServer(config);

const { setupRoutes } = await import("./routes");
setupRoutes(server);

server.start();
return server;
}

start();
38 changes: 38 additions & 0 deletions samples/subapp2-react-query-todoapp/src/server/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { PageRenderer } from "@xarc/react";
import { Todo } from "../app";

export function setupRoutes(server) {
let homeRenderer: PageRenderer;

server.route({
method: "GET",
path: "/",
async handler(request, reply) {
try {
if (!homeRenderer) {
homeRenderer = new PageRenderer({
pageTitle: "Electrode X Redux ToDo demo",
subApps: [
// { name: home.name, ssr: true },
// { name: Demo2.name, ssr: true }
{ name: Todo.name, ssr: false }
],
prodAssetData: {
cdnMap: "config/assets.json"
}
});
}
const context = await homeRenderer.render({ request });
reply.type("text/html");

if (context.user.cspHeader) {
reply.header(`content-security-policy`, context.user.cspHeader);
}

reply.send(context.result);
} catch (error) {
reply.send(error.stack);
}
}
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { React } from "@xarc/react";
import classNames from "classnames";
const custom = require("../styles/bootstrap.css");
import { create, mockTodos } from "../mock-fetch";
import { useMutation, QueryClient } from "@xarc/react-query";

const TodoInput = props => {
const { input } = props;
const mutation: any = useMutation("test", {
onMutate: variables => {
create(variables as any);
return mockTodos.todos;
},
onError: (error, variables, context) => {
(QueryClient as any).refetchQueries("test");
},
onSuccess: (data, variables, context) => {
(QueryClient as any).refetchQueries("test");
},
onSettled: (data, error, variables, context) => {
(QueryClient as any).refetchQueries("test");
}
});

return (
<div className={custom["input-group"]}>
<input
className={classNames(custom["form-control"])}
onChange={e => {
e.preventDefault();
props.setInput((e.target as any).value);
}}
value={input}
onKeyDown={e => {
if (e.keyCode === 13 && input) {
mutation.mutate({ content: input });
props.setInput("");
}
}}
/>
<span className={custom["input-group-btn"]}>
<button
className={classNames(custom["btn"], custom["btn-default"])}
onClick={() => {
if (input) {
mutation.mutate({ content: input });
props.setInput("");
}
}}
>
Add Todo
</button>
</span>
</div>
);
};

export default TodoInput;
36 changes: 36 additions & 0 deletions samples/subapp2-react-query-todoapp/src/todo/component/todo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { React } from "@xarc/react";
import { useMutation, useQuery } from "@xarc/react-query";
import { update, fetch, mockTodos } from "../mock-fetch";
const custom = require("../styles/bootstrap.css");

export const Todo = props => {
const { todo } = props;

const mutation: any = useMutation("test", {
onMutate: id => {
update(id);
return mockTodos.todos;
},
onError: (error, variables, context) => {
const { status, data } = useQuery("test1", fetch);
},
onSuccess: (data, variables, context) => {
const { status } = useQuery("test2", fetch);
},
onSettled: (data, error, variables, context) => {
const { status } = useQuery("test3", fetch);
}
});

return (
<li
className={custom["list-group-item"]}
onClick={() => {
mutation.mutate(todo.id);
}}
>
{todo.completed ? " ✅Completed -- " : " 🔥TODO -- "}
<span>{todo && todo.content}</span>
</li>
);
};
53 changes: 53 additions & 0 deletions samples/subapp2-react-query-todoapp/src/todo/component/todoapp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { React, ReactSubApp } from "@xarc/react";
import { useQuery } from "@xarc/react-query";
import classNames from "classnames";
const custom = require("../styles/bootstrap.css");
import { VISIBILITY_FILTERS } from "../constant";
import { fetch } from "../mock-fetch";
import TodoInput from "./todo-input";
import TodoList from "./todolist";
import VisibilityFilters from "./visibility-filters";

function TodoApp() {
const { status, data, error } = useQuery("test", fetch, {
// Refetch the data every second
refetchInterval: 1000
});
const [inputStr, setInputStr] = React.useState("");
const [curFilter, setCurFilter] = React.useState(VISIBILITY_FILTERS.ALL);

let todos = [];

if (data) {
todos = data.todos.filter(e => {
if (curFilter === VISIBILITY_FILTERS.ALL) {
return true;
} else if (curFilter === VISIBILITY_FILTERS.COMPLETED) {
if (e.completed) {
return true;
}

return false;
} else {
if (!e.completed) {
return true;
}

return false;
}
});
}

return (
<div style={{ margin: "24px" }}>
<h1 className={classNames(custom["page-header"], custom["text-center"])}>My To-do List</h1>
<TodoInput input={inputStr} setInput={setInputStr} />
<TodoList status={status} todos={todos} error={error} />
<VisibilityFilters setFilter={setCurFilter} />
</div>
);
}

export const subapp: ReactSubApp = {
Component: TodoApp
};
Loading

0 comments on commit 3dab9cd

Please sign in to comment.