Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 18, 2022 08:32 pm GMT

Remix :: CRUD com Supabase - Parte 05 - Trabalhando com formulrio

Nesta parte veremos o quanto fcil trabalhar com formulrios no Remix, iremos melhorar nossa estrutura de arquivos, colocando as coisas nos lugares certos para evitar cdigo duplicado e permitir assim o reaproveitamento na nossa aplicao.

Criando o modelo

Nas partes anteriores deste tutorial ns criamos a PostModel nos arquivos onde ele era necessrio, mas agora iremos deix-lo em lugar onde "quem precisar" na aplicao possa us-lo, portanto, crie o arquivo posts.model.ts dentro da pasta app/models/, de forma que ele fique assim: app/models/posts.model.ts. Edite-o e deixe desta forma:

export type PostsModel = {  post_id?: number  post_uuid?: string  post_author: string  post_title: string  post_text: string  post_situation?: string  post_created_at?: string}

Criando a API

Criado o modelo, podemos agora trabalhar com a API, que armazenar todas as aes que permitiro executar nosso CRUD, para isto, crie o arquivo supabase-api.ts dentro do diretrio app/api/, de forma que fique assim: app/api/supabase-api.ts.

  1. Edite o arquivo supabase-api.ts e import o PostsModels e o cliente supabase, deixando-o assim:
import { PostsModel } from '~/models/posts.model'import { supabase } from '~/utils/supabase-client.server'
  1. Ainda no supabase-api.ts. crie a funo getPosts, que ficar encarregada de realizar um select no Supabase para ns.
const getPosts = async () => {  const { data: posts } = await supabase    .from<PostsModel>('posts')    .select('*')    .order('post_id', { ascending: false })  return posts}
  1. Agora criaremos a funo addPost, que ficar responsvel por adicionar um registro novo.
const addPost = async ({ post_author, post_title, post_text }: PostsModel) => {  const { data, error } = await supabase.from<PostsModel>('posts').insert([    {      post_author: post_author,      post_title: post_title,      post_text: post_text,    },  ])  return { data, error }}
  1. Por fim, exporte as duas funces:
export { getPosts, addPost }

Criando a rota posts

Crie dentro da pasta routes um arquivo com nome posts.tsx e dentro dele faa os seguintes imports:

import { Link, LoaderFunction, Outlet, useLoaderData } from 'remix'import { getPosts } from '~/api/supabase-api'import { PostsModel } from '~/models/posts.model'
  • Link para criarmos o link que ir chamar o formulrio para iserir um novo registro;
  • LoaderFunction para tiparmos o mtodo loader que ficar responsvel por chamar a funo getPosts, que carrega os registros do banco de dados;
  • useLoaderData permite faamos o uso dos dados carregados pelo loader;
  • Outlet, este componente um wrapper em torno do Outlet do React Router com a capacidade de passar o estado da interface do usurio para rotas aninhadas. Ou seja, com ele ser possvel carregar a rota filha que conter o fomulrio dentro da rota pai posts.tsx;
  • getPosts a funo que carrega os registros do banco de dados; e
  • postModels o type model dos dados que viro do banco de dados.

Feito as importaes criaremos o mtodo loader para chamar a getPosts:

export const loader: LoaderFunction = async () => {  const posts = await getPosts()  return posts}

Agora iremos criar nosso componente Posts:

export default function Posts() {  const posts = useLoaderData<PostsModel[]>()  return (    <div style={{ fontFamily: 'system-ui, sans-serif', lineHeight: '1.4' }}>      <h1>Blog Remix com Supabase</h1>      <ul        style={{          listStyle: 'none',          display: 'flex',          flexDirection: 'row',          gap: '8px',        }}      >        <li>          <a            href='/'            style={{              textDecoration: 'none',              backgroundColor: '#ef62df',              color: '#fff',              padding: '8px',              borderRadius: '4px',              fontSize: '14px',            }}          >            Home          </a>        </li>        <li>          <Link            to={'new'}            style={{              textDecoration: 'none',              backgroundColor: '#62efd0',              color: '#0d6443',              padding: '8px',              borderRadius: '4px',              fontSize: '14px',            }}          >            Novo          </Link>        </li>      </ul>      <div>        <Outlet />      </div>      <div>        <ul style={{ listStyle: 'none' }}>          {posts?.map(post => (            <li key={post.post_uuid}>              <h3>{post.post_title}</h3>              <small>{post.post_author}</small>              <blockquote>{post.post_text}</blockquote>            </li>          ))}        </ul>      </div>    </div>  )}

E, por fim, chamaremos a funo ErrorBoundary do Remix, a qual permite que os erros sejam capturados dentro da rota que foi chamada, evitando assim que toda a aplicaose quebre:

export function ErrorBoundary({ error }: { error: Error }) {  return (    <div className='error-container'>      <h1> App Error</h1>      <pre> {error.message}</pre>    </div>  )}

Criando a pgina do fomulrio

Criado a pgina de listagem dos posts, iremos criar a pgina que conter o fomulrio que permitir que a gente insira novos registros, para isto crie a pasta posts dentro de routes, de forma que fique routes/posts. Dentro da pasta posts crie o arquivo new.tsx e faa as seguintes imports:

import { ActionFunction, Link, redirect } from 'remix'import { supabase } from '~/utils/supabase-client.server'
  • ActionFunction para tiparmos o mtodo do Remix chamado action que reponsvel por "capturar" as variveis enviadas pelo fomulrio. Na verdade action pega todas varveis de qualquer request na rota onde ele est.
  • redirect permite que a rota seja redirecionada
  • supabase o nosso cliente do Supabase

Feito os imports, chamaremos o mtodo action:

export const action: ActionFunction = async ({ request }) => {  const inputs = Object.fromEntries(await request.formData())  await supabase.from('posts').insert([inputs])  return redirect('.')}

Agora criaremos o componente NewPost que conter nosso formulrio:

export default function NewPost() {  return (    <div style={{ fontFamily: 'system-ui, sans-serif', lineHeight: '1.4' }}>      <h1>Novo post</h1>      <form        action='#'        method='post'        style={{          listStyle: 'none',          display: 'flex',          flexDirection: 'column',          gap: '8px',        }}      >        <div>          <label htmlFor=''>Ttulo</label>          <br />          <input type='text' name='post_title' />        </div>        <div>          <label htmlFor=''>Autor</label>          <br />          <input type='text' name='post_author' />        </div>        <div>          <label htmlFor=''>Texto</label>          <br />          <textarea            name='post_text'            id='post_text'            cols={30}            rows={10}          ></textarea>        </div>        <div>          <button            type='submit'            style={{              backgroundColor: '#62a4ef',              color: '#fff',              padding: '8px',              borderRadius: '4px',              border: 'none',              lineHeight: '1.4',              fontSize: '14px',              cursor: 'pointer',            }}          >            Enviar          </button>          <Link            to={'/posts'}            style={{              marginLeft: '10px',              textDecoration: 'none',              backgroundColor: '#ef62df',              color: '#fff',              padding: '8px',              borderRadius: '4px',              fontSize: '14px',            }}          >            Cancelar          </Link>          <br />        </div>      </form>    </div>  )}

Com isto finalizamos o formulrio e na parte 06 iremos criar nosso primeiro post atravs do formulrio criado. Te espero l!


Original Link: https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-05-trabalhando-com-formulario-5g14

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To