edge-city
git clone https://git.pyrossh.dev/edge-city
edge-city is a next level meta-framework for react that runs only on edge runtimes
example/src/pages/todos/page.jsx
| ce83445 | 1 | import { Suspense } from "react"; |
| ce83445 | 2 | import { ErrorBoundary } from "react-error-boundary"; |
| e6b4ebe | 3 | import { Helmet } from "react-helmet-async"; |
| c7f7584 | 4 | import { cache, useMutation } from "edge-city/data"; |
| e6b4ebe | 5 | import { useForm } from "react-hook-form"; |
| e6b4ebe | 6 | import { Button, TextField, Input } from "react-aria-components"; |
| f07784d | 7 | import Spinner from "@/components/Spinner/Spinner"; |
| ce83445 | 8 | import TodoList from "./TodoList"; |
| ce83445 | 9 | import { createTodo } from "@/services/todos.service"; |
| e284d5b | 10 | import "./page.css"; |
| e284d5b | 11 | |
| 0f7bd4a | 12 | export default function Page() { |
| ce83445 | 13 | const { |
| ce83445 | 14 | register, |
| ce83445 | 15 | handleSubmit, |
| ce83445 | 16 | reset, |
| ce83445 | 17 | formState: { errors }, |
| ce83445 | 18 | } = useForm(); |
| e284d5b | 19 | const { mutate, isMutating, err } = useMutation(async ({ text }) => { |
| e284d5b | 20 | await createTodo({ |
| e284d5b | 21 | text, |
| e284d5b | 22 | completed: false, |
| e6b4ebe | 23 | }); |
| f07784d | 24 | await cache.invalidate("todos"); |
| ce83445 | 25 | reset(); |
| 6b0984a | 26 | }); |
| e284d5b | 27 | return ( |
| 6b0984a | 28 | <div className="todos-page"> |
| 6b0984a | 29 | <h1 className="title">Todo List</h1> |
| 2292a7c | 30 | <Helmet> |
| 6b0984a | 31 | <title>Todo List</title> |
| 2292a7c | 32 | </Helmet> |
| 6b0984a | 33 | <div className="container"> |
| 6b0984a | 34 | <p className="subtitle">Share this page to collaborate with others.</p> |
| 2292a7c | 35 | <form onSubmit={handleSubmit(mutate)}> |
| d41c00d | 36 | <TextField isRequired isReadOnly={isMutating} aria-label="add-todo"> |
| e785cf4 | 37 | <Input id="text" aria-labelledby="text" aria-describedby="text" {...register("text")} placeholder="Add a todo item" /> |
| 2292a7c | 38 | {err?.text && <p>{err.text._errors[0]}</p>} |
| 2292a7c | 39 | </TextField> |
| e6b4ebe | 40 | <Button className="add-button" type="submit" isDisabled={isMutating}> |
| e6b4ebe | 41 | Add |
| e6b4ebe | 42 | </Button> |
| 2292a7c | 43 | </form> |
| f07784d | 44 | <ErrorBoundary onError={(err) => console.log("err", err)} fallback={<p>Oops something went wrong</p>}> |
| f07784d | 45 | <Suspense fallback={<Spinner />}> |
| ce83445 | 46 | <TodoList isMutating={isMutating} /> |
| ce83445 | 47 | </Suspense> |
| ce83445 | 48 | </ErrorBoundary> |
| 2292a7c | 49 | </div> |
| e284d5b | 50 | </div> |
| e6b4ebe | 51 | ); |
| e6b4ebe | 52 | } |