-
Notifications
You must be signed in to change notification settings - Fork 106
Add tutor finder to TinyFish-cookbook #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,3 @@ | ||||||||||||||
| VITE_SUPABASE_PROJECT_ID="hspjxcouamcdqrvqhkgg" | ||||||||||||||
| VITE_SUPABASE_PUBLISHABLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImhzcGp4Y291YW1jZHFydnFoa2dnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3Njk2NzI4NzEsImV4cCI6MjA4NTI0ODg3MX0.1A4KloHAiPP6ObODTZnXicntDqMfwDbQP-_FoW4eyUY" | ||||||||||||||
| VITE_SUPABASE_URL="https://hspjxcouamcdqrvqhkgg.supabase.co" | ||||||||||||||
|
Comment on lines
+1
to
+3
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not commit live Supabase credentials. These values appear to be real project identifiers and a JWT-style key; committing them (especially with 🔒 Example placeholder approach-VITE_SUPABASE_PROJECT_ID="hspjxcouamcdqrvqhkgg"
-VITE_SUPABASE_PUBLISHABLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
-VITE_SUPABASE_URL="https://hspjxcouamcdqrvqhkgg.supabase.co"
+VITE_SUPABASE_PROJECT_ID=
+VITE_SUPABASE_PUBLISHABLE_KEY=
+VITE_SUPABASE_URL=📝 Committable suggestion
Suggested change
🧰 Tools🪛 dotenv-linter (4.0.0)[warning] 1-1: [QuoteCharacter] The value has quote characters (', ") (QuoteCharacter) [warning] 2-2: [QuoteCharacter] The value has quote characters (', ") (QuoteCharacter) [warning] 3-3: [QuoteCharacter] The value has quote characters (', ") (QuoteCharacter) 🪛 Gitleaks (8.30.0)[high] 2-2: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data. (jwt) 🤖 Prompt for AI Agents |
||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,24 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Logs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *.log | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| npm-debug.log* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| yarn-debug.log* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| yarn-error.log* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pnpm-debug.log* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lerna-debug.log* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node_modules | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dist | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dist-ssr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *.local | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Editor directories and files | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .vscode/* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| !.vscode/extensions.json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .idea | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .DS_Store | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *.suo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *.ntvs* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *.njsproj | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *.sln | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *.sw? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check for .env files and Supabase integration
echo "=== Checking for .env files in tutor-finder ==="
find tutor-finder -maxdepth 2 -type f -name '.env*' 2>/dev/null | head -20
echo "=== Checking git tracked files that look like env files ==="
git ls-files tutor-finder | grep -E '\.(env|local)$' || echo "No tracked .env files found"
echo "=== Checking for Supabase references in codebase ==="
rg -i 'supabase' tutor-finder --type ts --type tsx --type js --type jsx -l
echo "=== Checking if .env is mentioned anywhere ==="
rg -i '\.env' tutor-finder --type md --type json -l
echo "=== Listing tutor-finder directory structure ==="
ls -la tutor-finder/ | head -30Repository: tinyfish-io/tinyfish-cookbook Length of output: 1768 🏁 Script executed: #!/bin/bash
# Verify what's in the tracked .env file
echo "=== Contents of tracked .env file ==="
cat tutor-finder/.env
echo ""
echo "=== Git history check: when was .env added ==="
git log --oneline --follow tutor-finder/.env | head -5Repository: tinyfish-io/tinyfish-cookbook Length of output: 533 Critical: Add The Required actions:
Gitignore update node_modules
dist
dist-ssr
*.local
+
+# Environment variables
+.env
+.env.local
+.env.*.local
# Editor directories and files📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| # Project Title - Exam Tutor Finder | ||
|
|
||
| **Live Link**: https://tinyfishtutorsfinder.lovable.app/ | ||
|
|
||
| ## What This Project Is - | ||
| The Exam Tutor Finder Tool is an AI-powered tutor discovery and comparison platform that helps students find the best competitive exam tutors from across the web in real time. | ||
|
|
||
| Instead of manually searching multiple tutoring websites, this system automatically: | ||
|
|
||
| 1) Uses AI to discover relevant tutor platforms based on user intent | ||
|
|
||
| 2) Uses the TinyFish Web Agent to browse tutor websites like a real user | ||
|
|
||
| 3) Extracts live tutor listings directly from source websites | ||
|
|
||
| 4) Normalizes tutor data into a structured, comparable format | ||
|
|
||
| 5) Returns a consolidated list of tutors that can be filtered and compared | ||
|
|
||
| The goal is to give students a single place to discover, evaluate, and choose tutors for competitive exams based on exam type, budget, teaching mode, and experience. | ||
|
|
||
| ## What to Expect | ||
|
|
||
| 1) Live tutor data extracted directly from real tutoring websites, ensuring up-to-date listings | ||
|
|
||
| 2) Fast multi-platform search using parallel browser agents | ||
|
|
||
| 3) Real-time progress updates while tutor websites are being scanned | ||
|
|
||
| 4) Clean, structured tutor results in standardized JSON format for easy comparison | ||
|
|
||
| 5) AI-focused matching to show only relevant tutors for selected competitive exams | ||
|
|
||
| 6) Easy comparison of tutors based on subjects, experience, teaching mode, and pricing | ||
|
|
||
| 7) Coverage across multiple global tutor marketplaces in one search | ||
|
|
||
| 8) Scalable system designed to handle multiple websites efficiently | ||
|
|
||
| **Demo Video** - https://drive.google.com/file/d/1GOe82HPSTilV_MGob09oexmoiRhEtfbW/view?usp=sharing | ||
|
|
||
| ## Code snippet - | ||
| ```bash | ||
| const response = await fetch("https://mino.ai/v1/automation/run-sse", { | ||
| method: "POST", | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| "X-API-Key": "sk-mino-YOUR_API_KEY", | ||
| }, | ||
| body: JSON.stringify({ | ||
| url: "https://www.superprof.com", | ||
| goal: "Extract tutor listings for competitive exams (SAT, ACT, AP, GRE, GMAT, Olympiads). Return JSON with tutorName, examsTaught, subjects, teachingMode, location, price, experience, qualifications, contactLink.", | ||
| browser_profile: "lite", | ||
| }), | ||
| }); | ||
|
|
||
| const reader = response.body!.getReader(); | ||
| const decoder = new TextDecoder(); | ||
|
|
||
| while (true) { | ||
| const { done, value } = await reader.read(); | ||
| if (done) break; | ||
|
|
||
| const chunk = decoder.decode(value); | ||
| for (const line of chunk.split("\n")) { | ||
| if (line.startsWith("data: ")) { | ||
| const data = JSON.parse(line.slice(6)); | ||
|
|
||
| if (data.streamingUrl) { | ||
| console.log("Live view:", data.streamingUrl); | ||
| } | ||
|
|
||
| if (data.type === "COMPLETE" && data.resultJson) { | ||
| console.log("Tutor Results:", data.resultJson); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Tech Stack | ||
| **Next.js (TypeScript)** | ||
|
|
||
| **Mino API** | ||
|
|
||
| **AI** | ||
|
|
||
| ## Architecture Diagram | ||
| ```mermaid | ||
| flowchart TB | ||
|
|
||
| %% ======================= | ||
| %% UI LAYER | ||
| %% ======================= | ||
| UI["USER INTERFACE<br/>(React + Tailwind + Lovable)"] | ||
|
|
||
| %% ======================= | ||
| %% ORCHESTRATION | ||
| %% ======================= | ||
| ORCH["Tender Search Orchestration Layer<br/>(Next.js API / Server Actions)"] | ||
|
|
||
| %% ======================= | ||
| %% SERVICES | ||
| %% ======================= | ||
| DB["SUPABASE<br/>(Cached Tenders & Metadata)"] | ||
| MINO["MINO API<br/>(Browser Automation)"] | ||
|
|
||
| %% ======================= | ||
| %% DETAILS | ||
| %% ======================= | ||
| DBD["• Cached tender listings<br/>• Deduplicated tenders<br/>• Historical records"] | ||
| MINOD["• Parallel web agents<br/>• Browse govt tender portals<br/>• Open tender pages<br/>• Extract structured fields<br/>• SSE streaming updates"] | ||
|
|
||
| %% ======================= | ||
| %% CONNECTIONS | ||
| %% ======================= | ||
| UI --> ORCH | ||
|
|
||
| ORCH --> DB | ||
| ORCH --> MINO | ||
|
|
||
| DB --> DBD | ||
| MINO --> MINOD | ||
| ``` | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "$schema": "https://ui.shadcn.com/schema.json", | ||
| "style": "default", | ||
| "rsc": false, | ||
| "tsx": true, | ||
| "tailwind": { | ||
| "config": "tailwind.config.ts", | ||
| "css": "src/index.css", | ||
| "baseColor": "slate", | ||
| "cssVariables": true, | ||
| "prefix": "" | ||
| }, | ||
| "aliases": { | ||
| "components": "@/components", | ||
| "utils": "@/lib/utils", | ||
| "ui": "@/components/ui", | ||
| "lib": "@/lib", | ||
| "hooks": "@/hooks" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import js from "@eslint/js"; | ||
| import globals from "globals"; | ||
| import reactHooks from "eslint-plugin-react-hooks"; | ||
| import reactRefresh from "eslint-plugin-react-refresh"; | ||
| import tseslint from "typescript-eslint"; | ||
|
|
||
| export default tseslint.config( | ||
| { ignores: ["dist"] }, | ||
| { | ||
| extends: [js.configs.recommended, ...tseslint.configs.recommended], | ||
| files: ["**/*.{ts,tsx}"], | ||
| languageOptions: { | ||
| ecmaVersion: 2020, | ||
| globals: globals.browser, | ||
| }, | ||
| plugins: { | ||
| "react-hooks": reactHooks, | ||
| "react-refresh": reactRefresh, | ||
| }, | ||
| rules: { | ||
| ...reactHooks.configs.recommended.rules, | ||
| "react-refresh/only-export-components": ["warn", { allowConstantExport: true }], | ||
| "@typescript-eslint/no-unused-vars": "off", | ||
| }, | ||
| }, | ||
| ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <!-- TODO: Set the document title to the name of your application --> | ||
| <title>Lovable App</title> | ||
| <meta name="description" content="Lovable Generated Project" /> | ||
| <meta name="author" content="Lovable" /> | ||
|
|
||
| <!-- TODO: Update og:title to match your application name --> | ||
| <meta property="og:title" content="Lovable App" /> | ||
| <meta property="og:description" content="Lovable Generated Project" /> | ||
| <meta property="og:type" content="website" /> | ||
| <meta property="og:image" content="https://lovable.dev/opengraph-image-p98pqg.png" /> | ||
|
|
||
| <meta name="twitter:card" content="summary_large_image" /> | ||
| <meta name="twitter:site" content="@Lovable" /> | ||
| <meta name="twitter:image" content="https://lovable.dev/opengraph-image-p98pqg.png" /> | ||
| </head> | ||
|
|
||
| <body> | ||
| <div id="root"></div> | ||
| <script type="module" src="/src/main.tsx"></script> | ||
| </body> | ||
| </html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
.envfile should be untracked and included in.gitignoreYou can try and create a new
.env.examplefile containing the required fields with empty values