Skip to content

Commit 93c7ea9

Browse files
committed
feat(ui): add mobile info modal for small screens
1 parent 39e1397 commit 93c7ea9

4 files changed

Lines changed: 91 additions & 2 deletions

File tree

src/Layout.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import { Outlet, useLocation } from "react-router-dom";
33
import cn from "@/utils/cn";
44
import NavBar from "@/components/Nav";
55
import Footer from "@/components/Footer";
6+
import MobileInfoModal from "@/components/MobileInfoModel";
67

78
const Layout = () => {
89
const location = useLocation();
910
const isHomePage = location.pathname === "/";
1011

1112
return (
1213
<>
14+
<MobileInfoModal />
1315
{!isHomePage && <NavBar />}
1416
<main
1517
className={cn(

src/components/MobileInfoModel.jsx

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { useState, useEffect } from "react";
2+
import { Monitor, Smartphone } from "lucide-react";
3+
import { useLocation } from "react-router-dom";
4+
5+
import { paths } from "@/routes";
6+
7+
const MobileInfoModal = () => {
8+
const location = useLocation();
9+
const [isOpen, setIsOpen] = useState(false);
10+
const [dismissed, setDismissed] = useState(false);
11+
12+
const handleContinue = () => {
13+
setIsOpen(false);
14+
setDismissed(true);
15+
};
16+
17+
const checkScreenSize = () => {
18+
const isMobile = window.innerWidth < 970;
19+
if (paths.includes(location.pathname) && isMobile && !dismissed) {
20+
setIsOpen(true);
21+
} else {
22+
setIsOpen(false);
23+
}
24+
};
25+
26+
useEffect(() => {
27+
checkScreenSize();
28+
29+
const handleResize = () => {
30+
checkScreenSize();
31+
};
32+
33+
const handleKeyDown = (e) => {
34+
if (e.key === "Escape") {
35+
setIsOpen(false);
36+
setDismissed(true);
37+
}
38+
};
39+
40+
window.addEventListener("resize", handleResize);
41+
window.addEventListener("keydown", handleKeyDown);
42+
43+
return () => {
44+
window.removeEventListener("resize", handleResize);
45+
window.removeEventListener("keydown", handleKeyDown);
46+
};
47+
}, [location.pathname, dismissed]);
48+
49+
return isOpen ? (
50+
<div className="fixed inset-0 z-50 bg-black/60 flex items-center justify-center">
51+
<div className="bg-[#374151] text-white p-6 rounded-2xl shadow-2xl w-full max-w-md mx-4 relative text-center">
52+
<div className="flex flex-col items-center gap-4">
53+
<div className="bg-[#6366f1]/10 rounded-full p-4">
54+
<Monitor className="w-8 h-8 text-[#6366f1]" />
55+
</div>
56+
<h2 className="text-xl font-semibold">Best Viewed on Desktop</h2>
57+
<p className="text-sm text-gray-300">
58+
Dev.tools is best experienced on wider screens
59+
</p>
60+
61+
<div className="flex items-center justify-center gap-4 py-2">
62+
<div className="flex flex-col items-center gap-1 opacity-50">
63+
<Smartphone className="w-6 h-6" />
64+
<span className="text-xs">Mobile</span>
65+
</div>
66+
<div className="text-2xl"></div>
67+
<div className="flex flex-col items-center gap-1 text-[#6366f1]">
68+
<Monitor className="w-6 h-6" />
69+
<span className="text-xs">Desktop</span>
70+
</div>
71+
</div>
72+
73+
<button
74+
onClick={handleContinue}
75+
className="mt-4 bg-[#6366f1] text-white px-4 py-2 rounded-md hover:bg-[#6366f1]/90 w-full"
76+
>
77+
Continue Anyway
78+
</button>
79+
</div>
80+
</div>
81+
</div>
82+
) : null;
83+
};
84+
85+
export default MobileInfoModal;

src/routes.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,6 @@ const routes = [
244244
},
245245
];
246246

247-
export { formatToolName, routes };
247+
const paths = routes.slice(1, -1).map(({ path }) => "/" + path);
248+
249+
export { formatToolName, routes, paths };

src/styles/output.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)