Site institucional com delivery e painel de gestão para um restaurante coreano real.
Cardápio online, carrinho, checkout e um painel onde o dono da loja cadastra pratos, acompanha pedidos e edita o conteúdo do site — sem precisar de programador.
A KIMORI é um restaurante de comida coreana em Douradina, no interior do Paraná. Este repositório tem o sistema completo que a loja usa no dia a dia:
- O site, onde o cliente vê o cardápio, monta o pedido e finaliza a compra.
- O painel, onde a loja cuida de produtos, categorias, pedidos e do próprio conteúdo do site.
Tudo em PHP puro, sem framework e sem build: é só copiar para o servidor e rodar. A escolha é proposital — o sistema precisa continuar simples de hospedar e de manter.
O projeto passou por um redesign guiado por três regras:
- A tela precisa ficar boa parada. Nada de card flutuando, elemento pulando ou animação decorativa. Só fade curto na entrada, hover discreto e transições de 200–400ms.
- Hierarquia antes de efeito. Título serifado grande, texto de apoio, ação clara. Muito espaço em branco.
- O administrador não precisa de manual. Todo botão tem nome escrito, toda exclusão explica o impacto, toda tela vazia diz qual é o próximo passo.
- Cardápio com busca instantânea e filtro por categoria
- Carrinho lateral que sobrevive ao recarregar a página (localStorage)
- Checkout em 3 passos com validação no navegador e no servidor, máscaras de telefone/CEP, formas de pagamento e campo de troco
- Seção de avaliações, localização com mapa e rota, contato que abre o WhatsApp com a mensagem já escrita
- Textos, fotos e ícones da home editáveis pelo painel
- Responsivo de verdade: o layout é reorganizado no celular, não só reduzido
| Tela | O que resolve |
|---|---|
| Dashboard | pedidos e vendas do dia, o que está em andamento, atalhos e vendas da semana |
| Pedidos | filtro por situação com contagem, busca, detalhe completo e impressão da comanda |
| Produtos | cadastrar, editar, duplicar, ativar/desativar e excluir — com upload de foto |
| Categorias | organizam o cardápio; a exclusão avisa quantos produtos vão junto |
| Clientes | histórico agregado por telefone (nº de pedidos, último pedido, total gasto) |
| Conteúdo do site | textos e fotos da home, por seção, com "restaurar padrão" |
| Rodapé do site | endereço, telefone, horários, redes sociais e créditos |
Ainda: tema claro/escuro, confirmação antes de qualquer ação destrutiva,
mensagens em português claro (nunca Error 500) e estados vazios que orientam.
Requisitos: PHP 8.1+, MySQL/MariaDB e Apache (XAMPP, WAMP, Laragon ou qualquer hospedagem compartilhada).
# 1. Clone dentro da pasta pública do servidor (ex.: C:\xampp\htdocs)
git clone <url-do-repositorio> kimori-website
cd kimori-website
# 2. Nada a configurar: os padrões do XAMPP (127.0.0.1 / root / sem senha)
# já vêm no app/config/config.php.-
Precisa de outro banco, ou vai hospedar o site? Os valores saem de variáveis de ambiente — veja
.env.example. Para mudar só a sua máquina, crieapp/config/config.local.phpcom as constantes que quiser trocar. -
Importe a estrutura do banco:
mysql -u root < sql/schema.sql- Crie o seu acesso ao painel (o repositório não traz nenhuma senha):
php tools/create-admin.php "Seu Nome" seu@email.com- Acesse:
| Site | http://localhost/kimori-website/ |
| Painel | http://localhost/kimori-website/pages/admin/login.php |
- No painel, cadastre as categorias e depois os pratos em Produtos › Adicionar produto. O cardápio começa vazio de propósito.
Atualizando um banco antigo? Os arquivos
sql/update_*.sqlcuidam de cada mudança de estrutura. Rode-os na ordem em que foram adicionados; nenhum deles apaga pedidos ou clientes.
O site roda em produção na Railway. Três coisas não são óbvias e já custaram um deploy quebrado cada:
Extensões do PHP. O runtime da hospedagem não traz pdo_mysql por padrão,
e sem ela toda conexão falha com could not find driver. As extensões
necessárias estão declaradas no composer.json — é de lá que o build as lê.
A senha do banco não pode ser referência. O MYSQL_ROOT_PASSWORD do
serviço de banco é uma variável selada: a Railway nunca devolve o valor dela,
nem ao resolver ${{MySQL.MYSQLPASSWORD}} para outro serviço. A referência
chega vazia no container e o PDO recusa com using password: NO. O DB_PASS
do serviço do site guarda o valor literal, e precisa ser atualizado à mão se a
senha for rotacionada.
As imagens precisam de volume. O disco do container é recriado a cada
deploy. Sem um volume montado no caminho de UPLOADS_PATH, toda foto enviada
pelo painel desaparece no deploy seguinte.
A lista completa de variáveis está no .env.example. O Caddyfile na raiz
existe para que os arquivos internos do repositório (schema do banco,
documentação, configuração) não fiquem acessíveis por URL.
kimori-website/
├── app/
│ ├── bootstrap.php # ponto único de inicialização
│ ├── config/ # config.php (lê o ambiente) e database.php
│ ├── includes/ # helpers, autenticação e layouts
│ └── models/ # Category, Product, Order, Customer, Admin, Review, Setting
├── api/ # cria pedido (checkout) e detalhe do pedido (painel)
├── assets/
│ ├── css/ # style.css (site) · admin.css (painel)
│ ├── js/ # um arquivo por tela, sem dependências
│ └── images/ # logo e ilustrações em SVG
├── pages/
│ ├── checkout.php
│ └── admin/ # login, dashboard, pedidos, produtos, categorias…
├── sql/ # schema.sql + migrações update_*.sql
├── tools/create-admin.php # cria o administrador com senha em hash
├── uploads/ # fotos enviadas pelo painel (fora do repositório)
└── index.php # página inicial
Toda a identidade sai de variáveis CSS no topo de assets/css/style.css e
assets/css/admin.css. Mudar a marca é mudar essas linhas:
| Token | Uso |
|---|---|
--color-background |
creme, fundo das páginas |
--color-surface |
branco dos cards |
--color-primary |
vermelho queimado (ações e destaques) |
--color-secondary |
marrom escuro dos títulos |
--color-accent |
dourado dos detalhes finos |
--font-display |
Marcellus — a serifada da logo, usada nos títulos |
--font-body |
Inter — textos, botões e formulários |
Há ainda escalas de espaçamento (--space-*), raios (--radius-*), sombras
(--shadow-*) e uma única duração de transição. Não use cor ou espaçamento
solto no meio do CSS — se falta um token, adicione ao topo do arquivo.
- Consultas com prepared statements (PDO) em todo o projeto
- Saída sempre escapada com
e()(htmlspecialchars) - Token CSRF em todo formulário e requisição de escrita
- Preço revalidado no servidor: o cliente nunca decide quanto paga
- Upload conferido por MIME real, tamanho e extensão; execução de script
bloqueada na pasta
uploads/ - Sessão com
httponly,SameSitee regeneração de ID no login - Senhas com
password_hash(bcrypt)
O repositório é público, então nada sensível entra nele:
app/config/config.local.php (se você criar um) e o conteúdo de
uploads/ (fotos enviadas pela loja) ficam fora do controle de versão, e nenhuma
senha de acesso vem no schema.sql.
Conventional Commits em português. Resumo:
<tipo>(<escopo>): <descrição no presente, minúscula, sem ponto final>
feat(produtos): adiciona ação de duplicar produto
fix(checkout): corrige validação do telefone com DDD
style(site): centraliza os números do topo da home
docs(readme): documenta a criação do administrador
Tipos: feat fix style refactor perf docs test build chore revert.
Ative o template e a validação da mensagem depois de clonar:
git config commit.template .gitmessage
git config core.hooksPath .githooksO guia completo — escopos, branches e o checklist antes de commitar — está em CONTRIBUTING.md.
Código e identidade visual da KIMORI Korean Food. O repositório é público para fins de estudo e portfólio: sinta-se livre para ler, aprender e se inspirar, mas a marca, o logo, as fotos e os textos do restaurante não podem ser reutilizados comercialmente.
KIMORI Korean Food · Douradina — PR

