S&T Marketplace
S&T Marketplace: shop products from verified sellers, pay with mobile money or your wallet and follow your delivery live.
Peça comida dos melhores restaurantes perto de você.
Translation pending
CommerceTypeScript · CSSGitHub @JotaNxxdevOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗App de delivery construído em Next.js 16 (App Router) + TypeScript, com backend próprio (rotas de API) e persistência de pedidos em Supabase (Postgres gratuito).
O projeto era um site estático (HTML/CSS/JS puro) sem backend: o cardápio
ficava fixo no código e os pedidos eram salvos só no localStorage do
navegador — ninguém além do próprio cliente via os pedidos, e eles somem se
o cache for limpo. Esta versão:
/, /restaurants/[id], /cart, /checkout, /orders, /profile)
em vez de esconder/mostrar <div>s com JavaScript.app/api/orders) que valida os pedidos e
recalcula os preços no servidor a partir do cardápio salvo no banco
— o cliente nunca pode adulterar o valor de um pedido.service_role key (nunca exposta ao cliente).innerHTML com texto
digitado pelo usuário, como observações e endereço, sem escapar) — o
React escapa esse conteúdo automaticamente.Intl.NumberFormat (via
toLocaleString), acessibilidade básica (aria-label, navegação por
teclado nos ícones clicáveis) e o carregamento da fonte por next/font.lib/seed-data.ts), então dá para rodar e navegar o app imediatamente;
só a criação de pedidos exige o banco configurado.npm install
npm run dev
Abra http://localhost:3000 — o cardápio aparece com dados de exemplo, mesmo sem configurar nada. Para poder finalizar pedidos de verdade, configure o Supabase (próxima seção).
supabase/schema.sql e rode.
Isso cria as tabelas (restaurants, menu_items, orders,
order_items), configura as políticas de RLS e já popula o cardápio
inicial (os mesmos restaurantes do protótipo).sb_secret_...service_role
(formato JWT, começa com eyJ...)anon — essa é
para uso no navegador, não serve pra isso..env.local.example para .env.local e preencha:
SUPABASE_URL=https://SEU-PROJETO.supabase.co
SUPABASE_SERVICE_ROLE_KEY=sua-service-role-key-aqui
NEXT_PUBLIC_SUPABASE_URL=https://SEU-PROJETO.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sua-publishable-key-aqui
As duas últimas são as mesmas usadas pelo login (ver próxima seção) —
NEXT_PUBLIC_SUPABASE_URL é igual a SUPABASE_URL, só que também
acessível pelo navegador (é só a URL do projeto, não é segredo).npm run dev. O cardápio passa a vir do banco e os pedidos
feitos em "Finalizar Pedido" são salvos nas tabelas orders/order_items..env.local já está no .gitignore — nunca será commitado.
supabase/schema.sql, rode também, nessa ordem, no
SQL Editor do Supabase:
supabase/migrations/002_auth_and_roles.sql
— cria a tabela profiles (com o papel de cada usuário) e liga
restaurants/orders à conta de quem é dono/fez o pedido.supabase/migrations/003_profile_and_restaurant_settings.sql
— adiciona telefone/foto ao perfil, cor/descrição à loja, e torna
pedido sem conta (visitante) uma coisa só do histórico.sb_publishable_... em projetos novos, ou a chave anon em projetos
antigos) e preencha NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY no
.env.local (e nas variáveis de ambiente da Vercel). Essa chave é
diferente da SUPABASE_SERVICE_ROLE_KEY — ela é feita pra ficar
exposta no navegador, protegida pelas políticas de RLS./signup vira cliente por padrão.
Pra virar administrador do sistema, cadastre sua própria conta pelo
app e depois rode no SQL Editor (troque pelo seu e-mail):
update profiles set role = 'admin' where email = '[email protected]';
/admin para: cadastrar
restaurantes, atribuir um dono a cada um (pelo e-mail da conta dele —
a pessoa precisa ter se cadastrado antes em /signup), ver todos os
pedidos do sistema e mudar o papel de qualquer usuário. É essa troca
de papel em Usuários que decide o que aparece pra cada pessoa na
tela de Perfil dela (o botão "Ir para o Painel..." correspondente)./restaurant para ver e
atualizar o status dos pedidos do próprio restaurante, gerenciar o
cardápio (criar/editar/excluir itens) e editar a própria loja em
/restaurant/settings (foto, cor, categoria, descrição, tempo e
taxa de entrega)./admin, /restaurant, /checkout, /orders e /profile são
protegidas por (middleware): sem login, redireciona pra
; a checagem de papel/dono (é admin? é dono deste restaurante?
é o próprio pedido?) acontece de novo em cada página e em cada Server
Action, então mesmo alguém adulterando uma requisição não consegue
agir fora do que o papel permite.Cada restaurante conecta a própria conta do Mercado Pago — o dinheiro de cada venda cai direto para o dono daquele restaurante, a plataforma nunca fica com o dinheiro em nenhum momento. Sem custo de mensalidade ou de setup; o Mercado Pago só desconta a taxa dele quando um pagamento é concluído de verdade (nada é cobrado em modo de teste).
.env.local (e depois nas variáveis de ambiente da
Vercel, marcando Production/Preview/Development):
MERCADOPAGO_CLIENT_ID=sua-client-id-aqui
MERCADOPAGO_CLIENT_SECRET=sua-client-secret-aqui
https://SEU-APP.vercel.app/api/mercadopago/callback
(troque pelo seu domínio real; em teste local seria
http://localhost:3000/api/mercadopago/callback).supabase/migrations/004_pix_payments.sql
e supabase/migrations/005_marketplace_and_order_details.sql
no SQL Editor do Supabase./restaurant/settings.Use as contas e cartões de teste do Mercado Pago: crie um usuário de teste vendedor (conecta ele como se fosse o dono do restaurante) e um usuário de teste comprador (faz o pedido) — o Pix simulado entre os dois é aprovado automaticamente em poucos segundos, sem custo.
Quando um restaurante estiver pronto pra receber pagamentos de verdade,
troque MERCADOPAGO_CLIENT_ID/MERCADOPAGO_CLIENT_SECRET pelas
credenciais de produção da sua aplicação (mesma tela) e peça pro
dono desconectar e conectar de novo — nenhuma outra mudança é necessária.
/signup (vira cliente) e só depois
um administrador a promove em /admin. Não existe um convite direto
por e-mail ainda.restaurants, sem criptografia adicional além do
acesso restrito por service_role/RLS já usado no resto do app — é
seguro nesse nível, mas nunca é exibido em tela nenhuma nem enviado ao
navegador. Se um dia o dono trocar a senha da conta Mercado Pago, pode
ser necessário desconectar e conectar de novo..env.local
(marcando Production, Preview e Development): SUPABASE_URL,
SUPABASE_SERVICE_ROLE_KEY, NEXT_PUBLIC_SUPABASE_URL,
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY e, se for usar Pix,
MERCADOPAGO_CLIENT_ID e MERCADOPAGO_CLIENT_SECRET. Se for usar o bot
de WhatsApp (whatsapp-bot/README.md), adicione também
WHATSAPP_BOT_API_TOKEN e WHATSAPP_BOT_URL.next build automaticamente.https://SEU-APP.vercel.app/api/mercadopago/callback) nas
credenciais da sua aplicação no painel do Mercado Pago — veja
"Pagamento com Pix" acima.app/ rotas (App Router)
page.tsx → "/" (busca restaurantes no servidor)
HomeClient.tsx → busca/categorias/carrossel (interativo)
restaurants/[id]/ → cardápio de um restaurante
cart/ → carrinho
checkout/ → formulário completo (entrega/retirada, pagamento) + PixPayment.tsx (QR Code)
orders/ → histórico de pedidos (exige login)
profile/ → perfil salvo no banco (nome/telefone/foto) + atalhos de painel
login/, signup/ → autenticação (Supabase Auth)
admin/ → painel do administrador (restaurantes, pedidos, usuários)
restaurant/ → painel do dono de restaurante (pedidos, cardápio, loja, Mercado Pago)
api/orders/route.ts → cria e lista pedidos (exige login, recalcula preços, gera Pix)
api/orders/[code]/payment-status/ → consultado pela tela de Pix enquanto aguarda pagamento
api/webhooks/mercadopago/ → recebe avisos de pagamento do Mercado Pago
api/mercadopago/connect, callback/ → fluxo OAuth de cada restaurante conectar a própria conta
components/ BackButton, BottomNav, SignOutButton
contexts/CartContext.tsx estado do carrinho (persistido em localStorage)
proxy.ts protege rotas que exigem login, renova a sessão
lib/
supabase.ts cliente Supabase (server-only, service_role key)
supabase-auth-browser.ts cliente de login para uso no navegador
auth.ts lê a sessão/papel do usuário atual (server-only)
mercadopago.ts cria/consulta pagamentos Pix e OAuth Connect (server-only)
restaurants.ts leitura de restaurantes (Supabase ou seed)
admin-data.ts consultas usadas pelo painel do administrador
restaurant-data.ts consultas/edição usadas pelo painel do dono de restaurante
seed-data.ts dados de exemplo/fallback
types.ts, format.ts
supabase/
schema.sql schema principal + RLS + dados iniciais
migrations/002_auth_and_roles.sql login, papéis e vínculos de dono
migrations/003_profile_and_restaurant_settings.sql perfil e loja editáveis
migrations/004_pix_payments.sql status de pagamento Pix nos pedidos
migrations/005_marketplace_and_order_details.sql Mercado Pago Connect + mais dados no pedido
proxy.ts/login/login se ainda não tiver
conta (o carrinho é mantido, feito no navegador, e continua intacto
depois do login).