Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions app/components/SafetyToolkit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
'use client'

import { motion } from 'framer-motion'
import { Bell, Download, Users, ScanSearch } from 'lucide-react'
import { useRouter } from 'next/navigation'
import { useTranslation } from '../lib/i18n/LanguageContext'

const cards = [
{
icon: ScanSearch,
action: '/scan',
color: 'from-blue-500/20 via-cyan-500/10 to-blue-600/20',
title: {
vi: 'Kiểm tra tức thì',
en: 'Instant check'
},
description: {
vi: 'Quét URL, hình ảnh hoặc tin nhắn đáng ngờ chỉ với một cú nhấp.',
en: 'Scan suspicious links, images, or messages in one tap.'
}
},
{
icon: Bell,
action: '/alerts',
color: 'from-amber-500/15 via-orange-500/10 to-amber-600/15',
title: {
vi: 'Cảnh báo nóng',
en: 'Live alerts'
},
description: {
vi: 'Cập nhật xu hướng lừa đảo mới nhất để tránh các chiêu trò mới.',
en: 'Stay ahead of emerging scam trends with fresh alerts.'
}
},
{
icon: Download,
action: '/extension',
color: 'from-emerald-500/15 via-green-500/10 to-emerald-600/15',
title: {
vi: 'Cài extension',
en: 'Install extension'
},
description: {
vi: 'Bảo vệ trình duyệt 24/7 với cảnh báo và kiểm tra tự động.',
en: 'Get always-on browser protection with automatic checks.'
}
},
{
icon: Users,
action: '/community',
color: 'from-indigo-500/15 via-purple-500/10 to-indigo-600/15',
title: {
vi: 'Cộng đồng hỗ trợ',
en: 'Community support'
},
description: {
vi: 'Học kinh nghiệm thực chiến từ cộng đồng và chuyên gia.',
en: 'Learn real-world tips from peers and experts.'
}
}
]
Comment on lines +8 to +61
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the app directory structure and verify routes
echo "=== App directory structure ==="
find app -type d -maxdepth 1 | sort

echo ""
echo "=== Checking for route implementations ==="
for route in scan alerts extension community; do
  echo "Checking /app/$route..."
  if [ -d "app/$route" ]; then
    ls -la "app/$route"
  else
    echo "  ⚠️  Directory app/$route does not exist"
  fi
done

echo ""
echo "=== Searching for page files in app directory ==="
fd -t f "page\.(tsx|ts|jsx|js)" app

Repository: maitamdev/Anti-Scam

Length of output: 2216


Fix broken /community route.

The cards array references four navigation routes, but /community is not properly implemented. While /scan, /alerts, and /extension all have corresponding page.tsx files, the /community route lacks a root page.tsx. The directory exists but only contains app/community/stories/page.tsx, which means navigating to /community will result in a 404 error. Either create a root page for /community or update the card's action to point to the existing /community/stories route.

🤖 Prompt for AI Agents
In app/components/SafetyToolkit.tsx around lines 8 to 61, the card for the
community action points to "/community" but there is no root
app/community/page.tsx (only app/community/stories/page.tsx), causing a 404; fix
by either creating a new root page.tsx at app/community/page.tsx that renders or
redirects to the stories page, or change the card's action to
"/community/stories" so it links to the existing route.


export default function SafetyToolkit() {
const router = useRouter()
const { language } = useTranslation()

return (
<div className="grid gap-4 sm:gap-6 md:grid-cols-2">
{cards.map((card, index) => {
const Icon = card.icon

return (
<motion.button
key={card.action}
onClick={() => router.push(card.action)}
type="button"
initial={{ opacity: 0, y: 12 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: index * 0.05 }}
aria-label={language === 'vi' ? card.title.vi : card.title.en}
className="relative overflow-hidden rounded-2xl border border-white/10 bg-white/5 p-5 text-left shadow-lg backdrop-blur-xl transition hover:-translate-y-1 hover:border-white/20"
>
<div className={`absolute inset-0 bg-gradient-to-br ${card.color} opacity-40`} />
<div className="relative flex items-start gap-4">
<div className="rounded-xl bg-white/10 p-3 text-white shadow-inner">
<Icon className="h-6 w-6" />
</div>
<div className="space-y-1">
<div className="flex items-center gap-2">
<span className="rounded-full bg-white/10 px-2 py-1 text-[11px] font-semibold uppercase tracking-wide text-cyan-200">
{index + 1 < 10 ? `0${index + 1}` : index + 1}
</span>
<p className="text-sm font-semibold text-cyan-100">
{language === 'vi' ? 'Bước tiếp theo' : 'Next step'}
</p>
</div>
<h3 className="text-lg font-bold text-white">
{language === 'vi' ? card.title.vi : card.title.en}
</h3>
<p className="text-sm text-gray-200">
{language === 'vi' ? card.description.vi : card.description.en}
</p>
</div>
</div>
</motion.button>
)
})}
</div>
)
}
30 changes: 30 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import FeatureShowcase from './components/FeatureShowcase'
import TestimonialCarousel from './components/TestimonialCarousel'
import ScamTypeCards from './components/ScamTypeCards'
import TypewriterText from './components/TypewriterText'
import SafetyToolkit from './components/SafetyToolkit'
import { useRouter } from 'next/navigation'
import { useTranslation } from './lib/i18n/LanguageContext'

Expand Down Expand Up @@ -573,6 +574,35 @@ export default function Home() {
</div>
</section>

{/* Safety Toolkit Section - NEW */}
<section className="py-12 sm:py-20 px-4">
<div className="max-w-6xl mx-auto">
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between mb-8 sm:mb-12"
>
<div>
<h2 className="text-2xl sm:text-3xl md:text-4xl font-bold mb-3 sm:mb-2">
{language === 'vi' ? 'Tăng tốc an toàn' : 'Accelerate your safety'}
</h2>
<p className="text-gray-400 max-w-2xl">
{language === 'vi'
? 'Chọn bước tiếp theo để tận dụng tối đa bộ công cụ chống lừa đảo.'
: 'Pick your next move to get the most from the anti-scam toolkit.'}
</p>
</div>
<div className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-3 py-1 text-xs font-semibold text-cyan-200">
<Sparkles className="h-4 w-4" />
{language === 'vi' ? 'Đề xuất thông minh' : 'Smart recommendations'}
</div>
</motion.div>

<SafetyToolkit />
</div>
</section>

{/* Testimonials Section - NEW */}
<section className="py-12 sm:py-20 px-4">
<div className="max-w-7xl mx-auto">
Expand Down