feat: updated logic

This commit is contained in:
2026-01-23 20:43:12 +00:00
parent 27f7660093
commit fa7d397018
3 changed files with 94 additions and 31 deletions

View File

@@ -4,10 +4,28 @@ import Hero from '@/components/Hero';
import Features from '@/components/Features'; import Features from '@/components/Features';
import HowItWorks from '@/components/HowItWorks'; import HowItWorks from '@/components/HowItWorks';
import CallToAction from '@/components/CallToAction'; import CallToAction from '@/components/CallToAction';
import Toast from '@/components/Toast';
import { useSearchParams, useRouter } from 'next/navigation';
import { Suspense, useEffect, useState } from 'react';
function HomeContent() {
const searchParams = useSearchParams();
const router = useRouter();
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const errorMsg = searchParams.get('error');
if (errorMsg) {
setError(errorMsg);
// Clean up URL
const newUrl = window.location.pathname;
window.history.replaceState({}, '', newUrl);
}
}, [searchParams]);
export default function Home() {
return ( return (
<main> <main>
{error && <Toast message={error} onClose={() => setError(null)} />}
<Hero /> <Hero />
<Features /> <Features />
<HowItWorks /> <HowItWorks />
@@ -15,3 +33,11 @@ export default function Home() {
</main> </main>
); );
} }
export default function Home() {
return (
<Suspense fallback={<main><Hero /><Features /><HowItWorks /><CallToAction /></main>}>
<HomeContent />
</Suspense>
);
}

View File

@@ -7,39 +7,39 @@ export default function SharePage({ params }: { params: { code: string } }) {
const code = params.code; const code = params.code;
useEffect(() => { useEffect(() => {
const deepLink = "nemia://share/" + code; try {
const playStoreLink = "https://play.google.com/store/apps/details?id=app.nemia.android"; const deepLink = "nemia://share/" + code;
const waitlistLink = "https://nemia.app/waitlist"; const playStoreLink = "https://play.google.com/store/apps/details?id=app.nemia.android";
const landingPage = "https://nemia.app"; const waitlistLink = "https://nemia.app/waitlist";
const landingPage = "https://nemia.app";
const userAgent = navigator.userAgent || navigator.vendor || (window as any).opera; const userAgent = navigator.userAgent || navigator.vendor || (window as any).opera;
// iOS Detection // iOS Detection
if (/iPad|iPhone|iPod/.test(userAgent) && !(window as any).MSStream) { if (/iPad|iPhone|iPod/.test(userAgent) && !(window as any).MSStream) {
window.location.href = waitlistLink; window.location.href = waitlistLink;
return; return;
}
// Android Detection
if (/android/i.test(userAgent)) {
// Try to open the app via Intent Scheme
// Fallback to Play Store if app not installed
const intentUrl =
"intent://share/" +
code +
"#Intent;scheme=nemia;package=app.nemia.android;S.browser_fallback_url=" +
encodeURIComponent(playStoreLink) +
";end";
window.location.href = intentUrl;
return;
}
// Desktop / Other: Stay on the page
} catch (e) {
console.error("Redirection error:", e);
window.location.href = `/?error=${encodeURIComponent("An error occurred while redirecting.")}`;
} }
// Android Detection
if (/android/i.test(userAgent)) {
// Try to open the app via Intent Scheme
const intentUrl =
"intent://share/" +
code +
"#Intent;scheme=nemia;package=app.nemia.android;S.browser_fallback_url=" +
encodeURIComponent(landingPage) +
";end";
window.location.href = intentUrl;
// Fallback attempt (optional, if intent fails)
// setTimeout(() => {
// window.location.href = playStoreLink;
// }, 2000);
return;
}
// Desktop / Other: Stay on the page or redirect to landing
// window.location.href = landingPage;
}, [code]); }, [code]);
return ( return (

37
components/Toast.tsx Normal file
View File

@@ -0,0 +1,37 @@
"use client";
import { useEffect, useState } from "react";
import { X } from "lucide-react";
interface ToastProps {
message: string;
onClose: () => void;
duration?: number;
}
export default function Toast({ message, onClose, duration = 5000 }: ToastProps) {
const [visible, setVisible] = useState(true);
useEffect(() => {
const timer = setTimeout(() => {
setVisible(false);
setTimeout(onClose, 300); // Wait for fade out animation
}, duration);
return () => clearTimeout(timer);
}, [duration, onClose]);
if (!message) return null;
return (
<div
className={`fixed top-5 left-1/2 transform -translate-x-1/2 z-50 flex items-center gap-3 px-4 py-3 bg-red-600 text-white rounded-lg shadow-lg transition-opacity duration-300 ${visible ? "opacity-100" : "opacity-0"
}`}
>
<span className="text-sm font-medium">{message}</span>
<button onClick={() => setVisible(false)} className="hover:opacity-80">
<X size={16} />
</button>
</div>
);
}