SaanKain

A playful, Filipino-inspired natural-language restaurant discovery prototype.

About SaanKain

Ever asked yourself: "Saan ba tayo kakain?" SaanKain lets you type that exact question — or anything similar — in natural language. Example: cheap sushi near makati open now. The app interprets the message, searches places, ranks results, and presents them in a clean, mobile-first UI.


How It Works

Six steps from question to delicious answer.

💬

You type it

cheap sushi near makati open now

01
02

LLM / Rule Parser

Groq LLM (or rule-based fallback) extracts cuisine · location · openNow

🔍
🧠

Location resolved

Browser Geolocation + Nominatim reverse-geocode → lat/lng coordinates

03
04

Places fetched

Foursquare Places API: query · near text or ll coordinates

📍
🏆

Smart ranking

Cuisine match scored · distance as tiebreaker

05
06

Results appear

Filter by category · Sort by name, type or distance · List or Gallery


Natural Language Parsing

Casual text → structured parameters. Groq LLM with a rule-based fallback — always deterministic.

parser output
{
cuisine: "sushi",
location: "makati",
openNow: true,
}

Uses Groq LLM (llama-3.1-8b-instruct) when available; falls back to regex rules. Extracts cuisine, location, and open‑now status.


Features

Everything packed into one playful prototype.

🗣️

Natural Language

Type free-text queries — no forms or dropdowns needed.

🧠

LLM + Rule Parser

Groq LLM with rule-based fallback extracts cuisine, location, and open status.

📍

Geolocation

Browser Geolocation + Nominatim reverse-geocode powers "near me" searches.

🗺️

Foursquare Places

Live place data via Foursquare Places API — queried by text or coordinates.

🎛️

Filter, Sort & View

Filter by category, sort by name/type/distance, switch list or gallery view.

🔖

Bookmarks & History

Save favourite spots and revisit past searches anytime.


Technology Stack

Chosen for speed, clarity, and interview-friendliness.

🏗️

Framework

Next.js (Full Stack)TypeScriptCSS
🎨

UI

TailwindCSSshadcn/uiFramer MotionLucide ReactRechartsSonnerVaulEmbla Carousel
⚙️

HTTP / AI

Axiosgroq-sdk
🔌

Integrations

Foursquare Places APIOpenStreetMap Nominatim

Engineering Practices

Patterns applied throughout the codebase.

🔒

TypeScript Strict Mode

strict: true in tsconfig — no any, full type safety across every module.

🏗️

Layered Architecture

lib/ → services/ → hooks/ → components/ — each layer has one responsibility.

🛡️

API Input Validation

Auth code, message length, and coordinate range validated before any logic runs.

🧠

LLM Output Guarded by Zod

Groq LLM response validated with a Zod schema; rule-based fallback always available.

🧪

Unit Tests — Vitest

Parser and validation modules covered with describe / it test suites under tests/.

💾

Safe localStorage

SSR guard + try/catch on all reads/writes. History capped at 50, bookmarks at 20.

⚙️

Env-based Configuration

All secrets and limits via environment variables — never hardcoded in library code.

🌐

SEO Metadata

Next.js metadata API: title, description, OpenGraph, and keywords defined in layout.

📲

Functional Decomposition

Breaking down complex functions into smaller, more manageable pieces.

🗃️

4-File Structure Page

Organizing page components into four distinct files for better maintainability.

📦

Single Responsibility Principle

Each function or class should have only one reason to change.

🍱

Separation of Concerns

Dividing a program into distinct sections where each section addresses a separate concern.

🔠

Naming Conventions

Using descriptive and consistent names for variables, functions, and classes.


Meet the Developer:

Ian Cedric Ramirez

Ian Cedric Ramirez

Full Stack Engineer

Full Stack Engineer3 years experience

Building playful, practical projects. When not coding, I explore mountains, beaches, and read books.