An Interest In:
Web News this Week
- April 26, 2024
- April 25, 2024
- April 24, 2024
- April 23, 2024
- April 22, 2024
- April 21, 2024
- April 20, 2024
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
.
- Edite o arquivo
supabase-api.ts
e import oPostsModels
e o clientesupabase
, deixando-o assim:
import { PostsModel } from '~/models/posts.model'import { supabase } from '~/utils/supabase-client.server'
- Ainda no
supabase-api.ts
. crie a funogetPosts
, que ficar encarregada de realizar umselect
no Supabase para ns.
const getPosts = async () => { const { data: posts } = await supabase .from<PostsModel>('posts') .select('*') .order('post_id', { ascending: false }) return posts}
- 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 }}
- 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 mtodoloader
que ficar responsvel por chamar a funogetPosts
, que carrega os registros do banco de dados;useLoaderData
permite faamos o uso dos dados carregados peloloader
;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 paiposts.tsx
;getPosts
a funo que carrega os registros do banco de dados; epostModels
otype 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 chamadoaction
que reponsvel por "capturar" as variveis enviadas pelo fomulrio. Na verdadeaction
pega todas varveis de qualquerrequest
na rota onde ele est.redirect
permite que a rota seja redirecionadasupabase
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
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To