diff --git a/apps/lms/app/apple-icon.png b/apps/lms/app/apple-icon.png
new file mode 100644
index 0000000..f93df67
Binary files /dev/null and b/apps/lms/app/apple-icon.png differ
diff --git a/apps/lms/app/favicon.ico b/apps/lms/app/favicon.ico
index 0e0e0c6..d8e4b35 100644
Binary files a/apps/lms/app/favicon.ico and b/apps/lms/app/favicon.ico differ
diff --git a/apps/lms/app/icon0.svg b/apps/lms/app/icon0.svg
new file mode 100644
index 0000000..a091f47
--- /dev/null
+++ b/apps/lms/app/icon0.svg
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/apps/lms/app/icon1.png b/apps/lms/app/icon1.png
new file mode 100644
index 0000000..d990e64
Binary files /dev/null and b/apps/lms/app/icon1.png differ
diff --git a/apps/lms/app/manifest.json b/apps/lms/app/manifest.json
new file mode 100644
index 0000000..4b7eb0b
--- /dev/null
+++ b/apps/lms/app/manifest.json
@@ -0,0 +1,21 @@
+{
+ "name": "BeeWise",
+ "short_name": "BeeWise",
+ "icons": [
+ {
+ "src": "/web-app-manifest-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png",
+ "purpose": "maskable"
+ },
+ {
+ "src": "/web-app-manifest-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "maskable"
+ }
+ ],
+ "theme_color": "#ffffff",
+ "background_color": "#ffffff",
+ "display": "standalone"
+}
diff --git a/apps/lms/next.config.ts b/apps/lms/next.config.ts
index 445d54e..b60f79e 100644
--- a/apps/lms/next.config.ts
+++ b/apps/lms/next.config.ts
@@ -38,14 +38,20 @@ const nextConfig: NextConfig = {
],
},
async rewrites() {
+ if (!apiBaseUrl) {
+ return [];
+ }
+
+ const formattedBaseUrl = apiBaseUrl.replace(/\/$/, "");
+
return [
{
source: "/api/ai/:path*",
- destination: `${apiBaseUrl}/api/ai/:path*`,
+ destination: `${formattedBaseUrl}/api/ai/:path*`,
},
{
source: "/api/:path*",
- destination: `${apiBaseUrl}/:path*`,
+ destination: `${formattedBaseUrl}/:path*`,
},
];
},
diff --git a/apps/sale/app/apple-icon.png b/apps/sale/app/apple-icon.png
new file mode 100644
index 0000000..f93df67
Binary files /dev/null and b/apps/sale/app/apple-icon.png differ
diff --git a/apps/sale/app/favicon.ico b/apps/sale/app/favicon.ico
index 0e0e0c6..d8e4b35 100644
Binary files a/apps/sale/app/favicon.ico and b/apps/sale/app/favicon.ico differ
diff --git a/apps/sale/app/icon0.svg b/apps/sale/app/icon0.svg
new file mode 100644
index 0000000..a091f47
--- /dev/null
+++ b/apps/sale/app/icon0.svg
@@ -0,0 +1,17 @@
+RealFaviconGeneratorhttps://realfavicongenerator.net
\ No newline at end of file
diff --git a/apps/sale/app/icon1.png b/apps/sale/app/icon1.png
new file mode 100644
index 0000000..d990e64
Binary files /dev/null and b/apps/sale/app/icon1.png differ
diff --git a/apps/sale/app/manifest.json b/apps/sale/app/manifest.json
new file mode 100644
index 0000000..4b7eb0b
--- /dev/null
+++ b/apps/sale/app/manifest.json
@@ -0,0 +1,21 @@
+{
+ "name": "BeeWise",
+ "short_name": "BeeWise",
+ "icons": [
+ {
+ "src": "/web-app-manifest-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png",
+ "purpose": "maskable"
+ },
+ {
+ "src": "/web-app-manifest-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "maskable"
+ }
+ ],
+ "theme_color": "#ffffff",
+ "background_color": "#ffffff",
+ "display": "standalone"
+}
diff --git a/apps/sale/features/landing/components/FeatureShowcaseSection.tsx b/apps/sale/features/landing/components/FeatureShowcaseSection.tsx
index e9fb6f9..a2bfb0c 100644
--- a/apps/sale/features/landing/components/FeatureShowcaseSection.tsx
+++ b/apps/sale/features/landing/components/FeatureShowcaseSection.tsx
@@ -69,7 +69,7 @@ const SHOWCASE_ITEMS: ShowcaseItem[] = [
title: "Gia Sư Được Xác Thực",
subtitle: "Hồ sơ minh bạch, uy tín tuyệt đối",
description:
- "Mọi gia sư trên BeeWise đều phải hoàn thành quy trình xác thực đa tầng gồm kiểm tra thông tin, bằng cấp chuyên môn, chứng chỉ quốc tế và phỏng vấn trực tiếp trước khi nhận lớp.",
+ "Mọi gia sư trên BeeWise đều phải hoàn thành quy trình xác thực đa tầng gồm kiểm tra thông tin, bằng cấp chuyên môn, chứng chỉ quốc tế và phỏng vấn trước khi nhận lớp.",
benefits: [
"100% hồ sơ được kiểm duyệt thực tế",
"Bằng cấp, chứng chỉ rõ ràng, công khai",
diff --git a/apps/sale/features/landing/components/HeroSection.tsx b/apps/sale/features/landing/components/HeroSection.tsx
index 947258b..3ab88a6 100644
--- a/apps/sale/features/landing/components/HeroSection.tsx
+++ b/apps/sale/features/landing/components/HeroSection.tsx
@@ -6,10 +6,12 @@ import Link from "next/link";
import { HeroMotion } from "@workspace/ui/components/HeroMotion";
import { HeroCarousel } from "./HeroCarousel";
import { LightningIcon } from "@phosphor-icons/react";
+import { FunnelIcon } from "lucide-react";
export function HeroSection() {
const router = useRouter();
const [query, setQuery] = useState("");
+ const [isFocused, setIsFocused] = useState(false);
const handleSearch = () => {
if (query.trim()) {
@@ -69,28 +71,58 @@ export function HeroSection() {
}}
aria-hidden="true"
/>
-
-
setQuery(e.target.value)}
- onKeyDown={(e) => {
- if (e.key === "Enter") handleSearch();
- }}
- />
+
+
+
setIsFocused(true)}
+ onBlur={() => setIsFocused(false)}
+ onChange={(e) => setQuery(e.target.value)}
+ onKeyDown={(e) => {
+ if (e.key === "Enter") handleSearch();
+ }}
+ />
+
+ {/* Running placeholder marquee for mobile when input is empty & not focused */}
+ {!query && !isFocused && (
+
+
+
+ Ví dụ: "Gia sư Toán lớp 12, học online,
+ 200.000đ/buổi"
+
+
+ Ví dụ: "Gia sư Toán lớp 12, học online,
+ 200.000đ/buổi"
+
+
+
+ )}
+
+
-
-
- Tìm kiếm thủ công
-
+
+
+ Hoặc:
+
+ Xem danh sách gia sư
+
+
+
+
+ Gợi ý:
+ {["Toán 12", "IELTS", "Tiếng Anh"].map((tag) => (
+
+ ))}
+
diff --git a/apps/sale/features/tutor-guide/components/TutorGuideHero.tsx b/apps/sale/features/tutor-guide/components/TutorGuideHero.tsx
index ca143bd..447a4fa 100644
--- a/apps/sale/features/tutor-guide/components/TutorGuideHero.tsx
+++ b/apps/sale/features/tutor-guide/components/TutorGuideHero.tsx
@@ -86,7 +86,7 @@ export function TutorGuideHero() {
>
{step.title}
-
- {step.body}
-
))}
diff --git a/apps/sale/features/tutor-guide/components/TutorGuideTrust.tsx b/apps/sale/features/tutor-guide/components/TutorGuideTrust.tsx
index 512c50f..4d8a5d4 100644
--- a/apps/sale/features/tutor-guide/components/TutorGuideTrust.tsx
+++ b/apps/sale/features/tutor-guide/components/TutorGuideTrust.tsx
@@ -131,7 +131,7 @@ export function TutorGuideTrust() {
Tìm Kiếm Gia Sư
diff --git a/apps/sale/next.config.ts b/apps/sale/next.config.ts
index d85b0c0..610f7b0 100644
--- a/apps/sale/next.config.ts
+++ b/apps/sale/next.config.ts
@@ -46,14 +46,20 @@ const nextConfig: NextConfig = {
],
},
async rewrites() {
+ if (!apiBaseUrl) {
+ return [];
+ }
+
+ const formattedBaseUrl = apiBaseUrl.replace(/\/$/, "");
+
return [
{
source: "/api/ai/:path*",
- destination: `${apiBaseUrl}/api/ai/:path*`,
+ destination: `${formattedBaseUrl}/api/ai/:path*`,
},
{
source: "/api/:path*",
- destination: `${apiBaseUrl}/:path*`,
+ destination: `${formattedBaseUrl}/:path*`,
},
];
},
diff --git a/apps/staff/next.config.ts b/apps/staff/next.config.ts
index e221881..212df77 100644
--- a/apps/staff/next.config.ts
+++ b/apps/staff/next.config.ts
@@ -38,10 +38,16 @@ const nextConfig: NextConfig = {
],
},
async rewrites() {
+ if (!apiBaseUrl) {
+ return [];
+ }
+
+ const formattedBaseUrl = apiBaseUrl.replace(/\/$/, "");
+
return [
{
source: "/api/:path*",
- destination: `${apiBaseUrl}/:path*`,
+ destination: `${formattedBaseUrl}/:path*`,
},
];
},
diff --git a/packages/ui/components/layout/Footer.tsx b/packages/ui/components/layout/Footer.tsx
index bfae5b3..a5f4d31 100644
--- a/packages/ui/components/layout/Footer.tsx
+++ b/packages/ui/components/layout/Footer.tsx
@@ -1,66 +1,93 @@
import Link from "next/link";
import Image from "next/image";
-const FOOTER_LINKS = [
+const QUICK_LINKS = [
+ { label: "Gia sư 1:1", href: "/tutors" },
+ { label: "Tìm lớp", href: "/classes" },
+ { label: "Trở thành gia sư", href: "/tutor-guide" },
+ { label: "Về chúng tôi", href: "/about-us" },
+];
+
+const LEGAL_LINKS = [
{ label: "Chính Sách Bảo Mật", href: "/privacy" },
{ label: "Điều Khoản Sử Dụng", href: "/terms" },
];
export function Footer() {
return (
-