Added image slider and docs to the prototype

This commit is contained in:
Yussif Yahuza 2025-05-09 19:23:41 +00:00
parent 39d89b64e6
commit b96d800005
57 changed files with 1621 additions and 23 deletions

270
app/docs/page.tsx Normal file
View File

@ -0,0 +1,270 @@
"use client";
import React from "react";
import ReactMarkdown, { Components } from "react-markdown";
import remarkGfm from "remark-gfm";
const ReadmePage = () => {
const readmeContent = `
## 📘 WODEY Deliverables Overview
Welcome to your WODEY UI/UX design package. This page provides everything your team needs to understand, preview, and implement the design assets developed for the WODEY Publishing Ecosystem.
## 📂 Whats Included
Your deliverables include high-fidelity UI mockups, design system components, and documentation that collectively represent the full user journey across all major WODEY touchpoints.
| Section | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------- |
| 01_Homepage | The landing experience for www.wodey.books including hero sections, genre browsing, and ebook discovery |
| 02_Author Studio | UI for authors to create, edit, preview, and publish multimedia ebooks |
| 03_Reader App | Reader-facing immersive interface with scroll & flip view modes |
| 04_Artist Marketplace | Asset browsing, upload flow, and commission request screens |
| 05_Advertiser Portal | Campaign setup, keyword targeting, and performance dashboards |
| 06_WODEY_Wallet | Revenue dashboard tracking ebook sales and ad earnings |
| 07_Design System | Colors, typography, button states, spacing, and reusable components |
| 08_Prototype_Flow | Clickable user journey demo |
## 🛠 How to Use These Files
Preview the Screens: Scroll through the design sections in logical flow
Download Assets: Use the "Download All Mockups" button to access the .zip file
## 🔗 Links
[Live Preview URL](https://woedii.yoursoftwareengineers.com)
[Download Full Zip File by clicking on the download icon](https://woedii.yoursoftwareengineers.com/slider)
## 🤝 Support
If you need help integrating these designs into code or want to schedule a handoff session, please contact:
UI/UX Design Lead: Daphne Augustine ([daphne@yoursoftwareengineers.com](mailto:daphne@yoursoftwareengineers.com))
Development Lead: Yussif Yahuza ([yussif@yoursoftwareengineers.com](mailto:yussif@yoursoftwareengineers.com))
`;
const components: Components = {
h1: ({ node, ...props }) => (
<h1
style={{
fontSize: "2.2em",
fontWeight: "600",
marginTop: "1.2em",
marginBottom: "0.6em",
borderBottom: "1px solid #eaeaea",
paddingBottom: "0.3em",
}}
{...props}
/>
),
h2: ({ node, ...props }) => (
<h2
style={{
fontSize: "1.8em",
fontWeight: "600",
marginTop: "1.2em",
marginBottom: "0.6em",
borderBottom: "1px solid #eaeaea",
paddingBottom: "0.3em",
}}
{...props}
/>
),
h3: ({ node, ...props }) => (
<h3
style={{
fontSize: "1.5em",
fontWeight: "600",
marginTop: "1.2em",
marginBottom: "0.6em",
}}
{...props}
/>
),
p: ({ node, ...props }) => (
<p style={{ marginBottom: "1.2em", lineHeight: "1.8" }} {...props} />
),
a: ({ node, ...props }) => (
<a
style={{ color: "#0366d6", textDecoration: "none", fontWeight: "500" }}
{...props}
/>
),
ul: ({ node, ...props }) => (
<ul
style={{
paddingLeft: "1.5em",
marginBottom: "1.2em",
listStyleType: "disc",
}}
{...props}
/>
),
ol: ({ node, ...props }) => (
<ol
style={{
paddingLeft: "1.5em",
marginBottom: "1.2em",
listStyleType: "decimal",
}}
{...props}
/>
),
li: ({ node, ...props }) => (
<li style={{ marginBottom: "0.4em" }} {...props} />
),
table: ({ node, ...props }) => (
<table
style={{
width: "100%",
borderCollapse: "collapse",
marginBottom: "1.2em",
boxShadow: "0 1px 3px rgba(0,0,0,0.08)",
border: "1px solid #dfe2e5",
}}
{...props}
/>
),
th: ({ node, ...props }) => (
<th
style={{
border: "1px solid #dfe2e5",
padding: "0.6em 0.8em",
textAlign: "left",
backgroundColor: "#f6f8fa",
fontWeight: "600",
}}
{...props}
/>
),
td: ({ node, ...props }) => (
<td
style={{
border: "1px solid #dfe2e5",
padding: "0.6em 0.8em",
textAlign: "left",
}}
{...props}
/>
),
pre: ({ node, children, ...props }) => (
<pre
style={{
backgroundColor: "#f6f8fa",
padding: "1em",
borderRadius: "6px",
overflowX: "auto",
fontSize: "0.9em",
lineHeight: "1.5",
}}
{...props}
>
{children}
</pre>
),
code: (props) => {
// Using `props: any` and casting to bypass TypeScript error with `inline` prop.
const {
node,
inline: isInline,
className,
children,
// Destructure known non-HTML props from react-markdown to prevent them from being spread onto the <code> tag
index,
siblingCount,
ordered,
checked,
style: _style, // if style is passed in props, avoid conflict with style object below
...htmlProps // Spread remaining props, assuming they are valid HTML attributes for <code>
} = props as any;
const codeStyleBase = {
fontFamily:
'SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace',
};
if (isInline) {
return (
<code
className={className}
style={{
...codeStyleBase,
backgroundColor: "rgba(27,31,35,0.07)", // Slightly adjusted for better visibility
padding: "0.2em 0.4em",
margin: "0 0.1em",
fontSize: "85%",
borderRadius: "3px",
}}
{...htmlProps}
>
{children}
</code>
);
}
// For block code (inside <pre>)
return (
<code
className={className} // className might contain "language-js" etc.
style={{
...codeStyleBase,
// Most styling for block code is handled by the <pre> wrapper
// However, ensure no extra padding/margin if pre handles it
padding: 0,
backgroundColor: "transparent", // Pre has the background
}}
{...htmlProps}
>
{children}
</code>
);
},
};
return (
<div
style={{
padding: "2rem",
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
lineHeight: "1.7",
color: "#24292e",
backgroundColor: "#ffffff",
maxWidth: "800px",
margin: "40px auto",
boxShadow: "0 4px 12px rgba(0,0,0,0.08)",
borderRadius: "8px",
}}
>
<ReactMarkdown components={components} remarkPlugins={[remarkGfm]}>
{readmeContent}
</ReactMarkdown>
<a
href="http://35.207.46.142/Wodey/wodey-prototype"
target="_blank"
rel="noopener noreferrer"
style={{
display: "inline-block",
marginTop: "2.5rem",
padding: "0.8rem 1.6rem",
backgroundColor: "#0366d6",
color: "white",
textDecoration: "none",
borderRadius: "6px",
fontWeight: "600",
textAlign: "center",
transition: "background-color 0.2s ease-in-out",
}}
onMouseOver={(e) => (e.currentTarget.style.backgroundColor = "#005cc5")}
onMouseOut={(e) => (e.currentTarget.style.backgroundColor = "#0366d6")}
>
Go to Project Repo
</a>
</div>
);
};
export default ReadmePage;

64
app/slider/page.tsx Normal file
View File

@ -0,0 +1,64 @@
import ImageSlider from "@/components/custom/ImageSlider";
const SliderPage = () => {
const images = [
"/assets/1.png",
"/assets/2.png",
"/assets/3.png",
"/assets/4.png",
"/assets/5.png",
"/assets/6.png",
"/assets/7.png",
"/assets/8.png",
"/assets/9.png",
"/assets/10.png",
"/assets/11.png",
"/assets/12.png",
"/assets/13.png",
"/assets/14.png",
"/assets/15.png",
"/assets/16.png",
"/assets/17.png",
"/assets/18.png",
"/assets/19.png",
"/assets/20.png",
"/assets/21.png",
"/assets/22.png",
"/assets/23.png",
"/assets/24.png",
"/assets/25.png",
"/assets/26.png",
"/assets/27.png",
"/assets/28.png",
"/assets/29.png",
"/assets/30.png",
"/assets/31.png",
"/assets/32.png",
"/assets/33.png",
"/assets/34.png",
"/assets/35.png",
"/assets/36.png",
"/assets/37.png",
"/assets/38.png",
"/assets/39.png",
"/assets/40.png",
"/assets/41.png",
"/assets/42.png",
"/assets/43.png",
"/assets/44.png",
"/assets/45.png",
"/assets/46.png",
"/assets/47.png",
"/assets/48.png",
"/assets/49.png",
];
return (
<div className="container mx-auto px-4 py-8">
<h1 className="text-3xl font-bold text-center mb-8">Image Slider</h1>
<ImageSlider images={images} />
</div>
);
};
export default SliderPage;

View File

@ -0,0 +1,176 @@
"use client";
import { useState, useEffect } from "react";
import Image from "next/image";
import { Button } from "@/components/ui/button";
import { ChevronLeft, ChevronRight, ArrowLeft, Download } from "lucide-react"; // Added Download
import { useRouter } from "next/navigation";
import JSZip from "jszip";
import { saveAs } from "file-saver";
interface ImageSliderProps {
images: string[];
}
const ImageSlider: React.FC<ImageSliderProps> = ({ images }) => {
const [currentIndex, setCurrentIndex] = useState(0);
const [isDownloading, setIsDownloading] = useState(false);
const [isHovered, setIsHovered] = useState(false); // New state for hover
const router = useRouter();
const goToPrevious = () => {
const isFirstImage = currentIndex === 0;
const newIndex = isFirstImage ? images.length - 1 : currentIndex - 1;
setCurrentIndex(newIndex);
};
const goToNext = () => {
const isLastImage = currentIndex === images.length - 1;
const newIndex = isLastImage ? 0 : currentIndex + 1;
setCurrentIndex(newIndex);
};
useEffect(() => {
let timer: NodeJS.Timeout;
if (!isHovered) {
// Only set timer if not hovered
timer = setTimeout(() => {
goToNext();
}, 5000); // Change image every 5 seconds
}
return () => clearTimeout(timer);
}, [currentIndex, images.length, isHovered, goToNext]); // Added isHovered and goToNext to dependency array
const handleDownloadAll = async () => {
if (!images || images.length === 0) return;
setIsDownloading(true);
const zip = new JSZip();
try {
for (let i = 0; i < images.length; i++) {
const response = await fetch(images[i]);
const blob = await response.blob();
// Extract filename from path, or use index as fallback
const filename =
images[i].substring(images[i].lastIndexOf("/") + 1) ||
`image_${i + 1}.png`;
zip.file(filename, blob);
}
const zipBlob = await zip.generateAsync({ type: "blob" });
saveAs(zipBlob, "images.zip");
} catch (error) {
console.error("Error zipping images:", error);
// Handle error (e.g., show a notification to the user)
} finally {
setIsDownloading(false);
}
};
if (!images || images.length === 0) {
return <p>No images to display.</p>;
}
return (
<div
className="relative w-full max-w-2xl mx-auto flex flex-col items-center rounded-lg shadow-lg bg-gray-100 dark:bg-gray-700 p-4"
onMouseEnter={() => setIsHovered(true)} // Set hovered to true
onMouseLeave={() => setIsHovered(false)} // Set hovered to false
>
<Button
variant="outline"
size="icon"
onClick={() => router.back()}
className="absolute top-4 left-4 text-black bg-black bg-opacity-50 hover:bg-opacity-75 z-10" // Added z-10
aria-label="Go back"
>
<ArrowLeft className="h-6 w-6" />
</Button>
<Button
variant="outline"
size="icon"
onClick={handleDownloadAll}
disabled={isDownloading}
className="absolute top-4 right-4 bg-black bg-opacity-50 text-black hover:bg-opacity-75 z-10"
aria-label="Download all images"
>
{isDownloading ? (
<svg
className="animate-spin h-5 w-5 text-white"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
) : (
<Download className="h-6 w-6" />
)}
</Button>
<div className="relative w-full overflow-hidden rounded-t-lg mt-12">
{" "}
{/* Added mt-12 to make space for back button */}
<div
className="flex transition-transform duration-500 ease-in-out"
style={{ transform: `translateX(-${currentIndex * 100}%)` }}
>
{images.map((src, index) => (
<div key={index} className="w-full flex-shrink-0 h-96 relative">
<Image
src={src}
alt={`Slide ${index + 1}`}
fill // Changed from layout="fill"
objectFit="contain"
priority={index === 0}
/>
</div>
))}
</div>
<Button
variant="outline"
size="icon"
className="absolute top-1/2 left-2 transform -translate-y-1/2 bg-black bg-opacity-50 text-white hover:bg-opacity-75"
onClick={goToPrevious}
>
<ChevronLeft className="h-6 w-6" />
</Button>
<Button
variant="outline"
size="icon"
className="absolute top-1/2 right-2 transform -translate-y-1/2 bg-black bg-opacity-50 text-white hover:bg-opacity-75"
onClick={goToNext}
>
<ChevronRight className="h-6 w-6" />
</Button>
</div>
<div className="flex items-center justify-center space-x-2 pt-4 pb-1">
{" "}
{/* Changed py-4 to pt-4 pb-1 to move dots lower */}
{images.map((_, index) => (
<button
key={index}
className={`w-3 h-3 rounded-full ${
currentIndex === index
? "bg-blue-500"
: "bg-gray-400 hover:bg-gray-500"
}`}
onClick={() => setCurrentIndex(index)}
aria-label={`Go to slide ${index + 1}`}
/>
))}
</div>
</div>
);
};
export default ImageSlider;

View File

@ -1,9 +1,14 @@
import { Bell, Menu } from 'lucide-react'; import { Bell, Menu } from "lucide-react";
import { Search } from 'lucide-react'; import { Search } from "lucide-react";
import { Input } from '@/components/ui/input'; import { Input } from "@/components/ui/input";
import { Dispatch, SetStateAction } from 'react'; import { Dispatch, SetStateAction } from "react";
import Link from "next/link";
export default function Navbar({ setDrawerOpen }: { setDrawerOpen?: Dispatch<SetStateAction<boolean>> }) { export default function Navbar({
setDrawerOpen,
}: {
setDrawerOpen?: Dispatch<SetStateAction<boolean>>;
}) {
return ( return (
<div className="flex items-center justify-between w-full h-[52px] xs:h-[56px] sm:h-[64px] md:h-[75px] bg-white px-2 xs:px-3 sm:px-4 md:px-6 lg:px-10"> <div className="flex items-center justify-between w-full h-[52px] xs:h-[56px] sm:h-[64px] md:h-[75px] bg-white px-2 xs:px-3 sm:px-4 md:px-6 lg:px-10">
{/* Hamburger menu for mobile */} {/* Hamburger menu for mobile */}
@ -29,7 +34,10 @@ export default function Navbar({ setDrawerOpen }: { setDrawerOpen?: Dispatch<Set
</div> </div>
<div className="flex items-center gap-1 xs:gap-2 sm:gap-3 md:gap-4 lg:gap-6"> <div className="flex items-center gap-1 xs:gap-2 sm:gap-3 md:gap-4 lg:gap-6">
<div className="relative cursor-pointer"> <div className="relative cursor-pointer">
<Bell size={16} className="text-[#222] xs:text-[18px] sm:text-[20px] md:text-[22px]" /> <Bell
size={16}
className="text-[#222] xs:text-[18px] sm:text-[20px] md:text-[22px]"
/>
<span className="absolute top-[-2px] right-0 w-1 h-1 xs:w-1.5 xs:h-1.5 sm:w-2 sm:h-2 bg-[#FF3B30] rounded-full border-[1.5px] border-white" /> <span className="absolute top-[-2px] right-0 w-1 h-1 xs:w-1.5 xs:h-1.5 sm:w-2 sm:h-2 bg-[#FF3B30] rounded-full border-[1.5px] border-white" />
</div> </div>
<div className="flex items-center cursor-pointer"> <div className="flex items-center cursor-pointer">
@ -40,6 +48,10 @@ export default function Navbar({ setDrawerOpen }: { setDrawerOpen?: Dispatch<Set
+ +
</div> </div>
</div> </div>
<Link href="/creator">Creator</Link>
<Link href="/marketplace/artists">Marketplace</Link>
<Link href="/slider">Slider</Link>
<Link href="/docs">Docs</Link>
</div> </div>
</div> </div>
); );

View File

@ -1,11 +1,12 @@
'use client'; "use client";
import Image from 'next/image'; import Image from "next/image";
import { Input } from '@/components/ui/input'; import { Input } from "@/components/ui/input";
import { Bell, Heart, ShoppingCart, SquarePen, Menu } from 'lucide-react'; import { Bell, Heart, ShoppingCart, SquarePen, Menu } from "lucide-react";
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
import { Button } from '@/components/ui/button'; import { Button } from "@/components/ui/button";
import { useState } from 'react'; import { useState } from "react";
import Link from "next/link";
function MarketplaceNavbar() { function MarketplaceNavbar() {
const [isMenuOpen, setIsMenuOpen] = useState(false); const [isMenuOpen, setIsMenuOpen] = useState(false);
@ -15,8 +16,16 @@ function MarketplaceNavbar() {
<div className="container-main h-[56px] flex items-center justify-between px-4 md:px-6"> <div className="container-main h-[56px] flex items-center justify-between px-4 md:px-6">
{/* Logo and Brand */} {/* Logo and Brand */}
<div className="flex items-center gap-2 min-w-[120px] md:min-w-[180px]"> <div className="flex items-center gap-2 min-w-[120px] md:min-w-[180px]">
<Image src="/marketplacelogo.png" alt="Woedii Logo" width={40} height={40} className="object-contain" /> <Image
<span className="text-white text-xl md:text-2xl ml-1 font-normal">Wodey</span> src="/marketplacelogo.png"
alt="Woedii Logo"
width={40}
height={40}
className="object-contain"
/>
<span className="text-white text-xl md:text-2xl ml-1 font-normal">
Wodey
</span>
</div> </div>
{/* Mobile Menu Button */} {/* Mobile Menu Button */}
@ -29,8 +38,23 @@ function MarketplaceNavbar() {
{/* Search Bar - Hidden on mobile */} {/* Search Bar - Hidden on mobile */}
<div className="hidden md:flex flex-1 justify-center"> <div className="hidden md:flex flex-1 justify-center">
<div className="flex items-center bg-[#F2F4F8] rounded-[8px] px-4" style={{ width: 400, height: 40, gap: 8 }}> <div
<svg className="text-[#6B7280] mr-2" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="8.5" cy="8.5" r="5.75"/><path d="M16 16l-3.5-3.5"/></svg> className="flex items-center bg-[#F2F4F8] rounded-[8px] px-4"
style={{ width: 400, height: 40, gap: 8 }}
>
<svg
className="text-[#6B7280] mr-2"
width="18"
height="18"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx="8.5" cy="8.5" r="5.75" />
<path d="M16 16l-3.5-3.5" />
</svg>
<Input <Input
type="text" type="text"
placeholder="Search images, videos, fonts, graphics and more" placeholder="Search images, videos, fonts, graphics and more"
@ -72,7 +96,10 @@ function MarketplaceNavbar() {
</div> </div>
{/* Create Button */} {/* Create Button */}
<a href="/creator"> <a href="/creator">
<Button className="flex items-center gap-2 bg-[#0093A5] text-white px-3 md:px-5 py-2 rounded-lg font-medium text-sm md:text-base transition-colors ml-2 md:ml-4 hover:bg-[#007a87] cursor-pointer" type="button"> <Button
className="flex items-center gap-2 bg-[#0093A5] text-white px-3 md:px-5 py-2 rounded-lg font-medium text-sm md:text-base transition-colors ml-2 md:ml-4 hover:bg-[#007a87] cursor-pointer"
type="button"
>
<SquarePen size={18} /> <SquarePen size={18} />
<span className="hidden sm:inline">Create</span> <span className="hidden sm:inline">Create</span>
</Button> </Button>
@ -80,11 +107,32 @@ function MarketplaceNavbar() {
</div> </div>
{/* Mobile Menu */} {/* Mobile Menu */}
<div className={`absolute top-[56px] left-0 right-0 bg-[#010313] z-50 md:hidden transition-all duration-300 ease-in-out transform ${isMenuOpen ? 'translate-y-0 opacity-100' : '-translate-y-4 opacity-0 pointer-events-none'}`}> <div
className={`absolute top-[56px] left-0 right-0 bg-[#010313] z-50 md:hidden transition-all duration-300 ease-in-out transform ${
isMenuOpen
? "translate-y-0 opacity-100"
: "-translate-y-4 opacity-0 pointer-events-none"
}`}
>
<div className="container-main py-4"> <div className="container-main py-4">
{/* Mobile Search */} {/* Mobile Search */}
<div className="flex items-center bg-[#F2F4F8] rounded-[8px] px-4 mb-4" style={{ height: 40, gap: 8 }}> <div
<svg className="text-[#6B7280] mr-2" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="8.5" cy="8.5" r="5.75"/><path d="M16 16l-3.5-3.5"/></svg> className="flex items-center bg-[#F2F4F8] rounded-[8px] px-4 mb-4"
style={{ height: 40, gap: 8 }}
>
<svg
className="text-[#6B7280] mr-2"
width="18"
height="18"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx="8.5" cy="8.5" r="5.75" />
<path d="M16 16l-3.5-3.5" />
</svg>
<Input <Input
type="text" type="text"
placeholder="Search..." placeholder="Search..."
@ -137,6 +185,16 @@ function MarketplaceSecondaryMenu() {
<li className="cursor-pointer">Audios</li> <li className="cursor-pointer">Audios</li>
<li className="cursor-pointer">Gifs</li> <li className="cursor-pointer">Gifs</li>
<li className="cursor-pointer">Fonts</li> <li className="cursor-pointer">Fonts</li>
<li className="cursor-pointer">
<Link href="/slider" className="text-white hover:text-gray-300">
Slider
</Link>
</li>
<li className="cursor-pointer">
<Link href="/docs" className="text-white hover:text-gray-300">
Docs
</Link>
</li>
</ul> </ul>
</div> </div>
</div> </div>

38
docs/deliverables.md Normal file
View File

@ -0,0 +1,38 @@
📘 WODEY Deliverables Overview
Welcome to your WODEY UI/UX design package. This page provides everything your team needs to understand, preview, and implement the design assets developed for the WODEY Publishing Ecosystem.
📂 Whats Included
Your deliverables include high-fidelity UI mockups, design system components, and documentation that collectively represent the full user journey across all major WODEY touchpoints.
| Section | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------- |
| 01_Homepage | The landing experience for www.wodey.books including hero sections, genre browsing, and ebook discovery |
| 02_Author Studio | UI for authors to create, edit, preview, and publish multimedia ebooks |
| 03_Reader App | Reader-facing immersive interface with scroll & flip view modes |
| 04_Artist Marketplace | Asset browsing, upload flow, and commission request screens |
| 05_Advertiser Portal | Campaign setup, keyword targeting, and performance dashboards |
| 06_WODEY_Wallet | Revenue dashboard tracking ebook sales and ad earnings |
| 07_DesignS ystem | Colors, typography, button states, spacing, and reusable components |
| 08_Prototype_Flow | Clickable user journey demo |
🛠 How to Use These Files
Preview the Screens: Scroll through the design sections in logical flow
Download Assets: Use the "Download All Mockups" button to access the .zip file
🔗 Links
[Live Preview URL](https://woedii.yoursoftwareengineers.com)
[Download Full Zip File by clicking on the download icon](https://woedii.yoursoftwareengineers.com/slider)
🤝 Support
If you need help integrating these designs into code or want to schedule a handoff session, please contact:
UI/UX Design Lead: Daphne Augustine ([daphne@yoursoftwareengineers.com](mailto:daphne@yoursoftwareengineers.com))
Development Lead: Yussif Yahuza ([yussif@yoursoftwareengineers.com](mailto:yussif@yoursoftwareengineers.com))

View File

@ -18,17 +18,22 @@
"@radix-ui/react-tooltip": "^1.2.4", "@radix-ui/react-tooltip": "^1.2.4",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"file-saver": "^2.0.5",
"iconsax-react": "^0.0.8", "iconsax-react": "^0.0.8",
"jszip": "^3.10.1",
"lucide-react": "^0.503.0", "lucide-react": "^0.503.0",
"next": "15.3.1", "next": "15.3.1",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-markdown": "^10.1.0",
"remark-gfm": "^4.0.1",
"tailwind-merge": "^3.2.0" "tailwind-merge": "^3.2.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3", "@eslint/eslintrc": "^3",
"@tailwindcss/postcss": "^4", "@tailwindcss/postcss": "^4",
"@types/file-saver": "^2.0.7",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19", "@types/react-dom": "^19",

File diff suppressed because it is too large Load Diff

BIN
public/assets/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 KiB

BIN
public/assets/10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

BIN
public/assets/11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 KiB

BIN
public/assets/12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

BIN
public/assets/13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

BIN
public/assets/14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

BIN
public/assets/15.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 KiB

BIN
public/assets/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 KiB

BIN
public/assets/17.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

BIN
public/assets/18.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

BIN
public/assets/19.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

BIN
public/assets/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
public/assets/20.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

BIN
public/assets/21.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

BIN
public/assets/22.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
public/assets/23.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

BIN
public/assets/24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

BIN
public/assets/25.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
public/assets/26.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

BIN
public/assets/27.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
public/assets/28.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
public/assets/29.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
public/assets/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

BIN
public/assets/30.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

BIN
public/assets/31.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

BIN
public/assets/32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

BIN
public/assets/33.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

BIN
public/assets/34.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
public/assets/35.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

BIN
public/assets/36.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

BIN
public/assets/37.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

BIN
public/assets/38.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

BIN
public/assets/39.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
public/assets/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
public/assets/40.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
public/assets/41.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
public/assets/42.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
public/assets/43.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
public/assets/44.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
public/assets/45.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 KiB

BIN
public/assets/46.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

BIN
public/assets/47.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
public/assets/48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 KiB

BIN
public/assets/49.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
public/assets/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
public/assets/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

BIN
public/assets/7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

BIN
public/assets/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

BIN
public/assets/9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB