Skip to content

Commit

Permalink
Add PhoneMockup component and enhance Draft page layout with AppHeade…
Browse files Browse the repository at this point in the history
…r and AppNav
  • Loading branch information
fwedwicc committed Jan 7, 2025
1 parent c2ba5a2 commit b79bdf9
Showing 1 changed file with 117 additions and 5 deletions.
122 changes: 117 additions & 5 deletions src/pages/Draft.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,134 @@
import React from 'react';
import React from 'react'
import useLenisScroll from '../hooks/useLenisScroll'
import useScrollToTop from '../hooks/useScrollToTop'
import useScrollToTop from '../hooks/useScrollToTop';
import { motion } from 'framer-motion'

const Draft = () => {
useLenisScroll();
useScrollToTop();

const PhoneMockup = ({ children }) => {
return (
<>
{/* Phone Mockup */}
<div className='relative border-[0.5rem] h-[44.5rem] w-[22.5rem] rounded-[2rem] ring-2 ring-neutral-400 bg-neutral-700/40 border-neutral-900'>
{/* Sound Buttons */}
<div className='absolute top-20 -left-3 flex flex-col gap-3'>
{[0, 1, 2].map((index) => (
<div
className={`rounded-full w-2 bg-neutral-900 border-neutral-400 border-l-2 ${index === 0 ? 'h-7' : 'h-10'}`} key={index}>
</div>
))}
</div>
{/* Power Button */}
<div className='absolute top-[9.2rem] border-neutral-400 border-r-2 -right-3 rounded-full h-16 w-2 bg-neutral-900'></div>
{/* Camera */}
<div className='absolute rounded-full h-[1.3rem] w-20 top-3 left-1/2 transform -translate-x-1/2 bg-neutral-900'></div>
{/* Phone Header */}
<div className={`absolute w-full flex justify-between items-center pt-2.5 px-3.5 text-white`}>
<p className="leading-relaxed text-xs font-semibold">
4:17
</p>
<div className='flex items-center gap-1.5'>
{[
'M18.375 2.25c-1.035 0-1.875.84-1.875 1.875v15.75c0 1.035.84 1.875 1.875 1.875h.75c1.035 0 1.875-.84 1.875-1.875V4.125c0-1.036-.84-1.875-1.875-1.875h-.75ZM9.75 8.625c0-1.036.84-1.875 1.875-1.875h.75c1.036 0 1.875.84 1.875 1.875v11.25c0 1.035-.84 1.875-1.875 1.875h-.75a1.875 1.875 0 0 1-1.875-1.875V8.625ZM3 13.125c0-1.036.84-1.875 1.875-1.875h.75c1.036 0 1.875.84 1.875 1.875v6.75c0 1.035-.84 1.875-1.875 1.875h-.75A1.875 1.875 0 0 1 3 19.875v-6.75Z',
'M1.371 8.143c5.858-5.857 15.356-5.857 21.213 0a.75.75 0 0 1 0 1.061l-.53.53a.75.75 0 0 1-1.06 0c-4.98-4.979-13.053-4.979-18.032 0a.75.75 0 0 1-1.06 0l-.53-.53a.75.75 0 0 1 0-1.06Zm3.182 3.182c4.1-4.1 10.749-4.1 14.85 0a.75.75 0 0 1 0 1.061l-.53.53a.75.75 0 0 1-1.062 0 8.25 8.25 0 0 0-11.667 0 .75.75 0 0 1-1.06 0l-.53-.53a.75.75 0 0 1 0-1.06Zm3.204 3.182a6 6 0 0 1 8.486 0 .75.75 0 0 1 0 1.061l-.53.53a.75.75 0 0 1-1.061 0 3.75 3.75 0 0 0-5.304 0 .75.75 0 0 1-1.06 0l-.53-.53a.75.75 0 0 1 0-1.06Zm3.182 3.182a1.5 1.5 0 0 1 2.122 0 .75.75 0 0 1 0 1.061l-.53.53a.75.75 0 0 1-1.061 0l-.53-.53a.75.75 0 0 1 0-1.06Z',
'M3.75 6.75a3 3 0 0 0-3 3v6a3 3 0 0 0 3 3h15a3 3 0 0 0 3-3v-.037c.856-.174 1.5-.93 1.5-1.838v-2.25c0-.907-.644-1.664-1.5-1.837V9.75a3 3 0 0 0-3-3h-15Zm15 1.5a1.5 1.5 0 0 1 1.5 1.5v6a1.5 1.5 0 0 1-1.5 1.5h-15a1.5 1.5 0 0 1-1.5-1.5v-6a1.5 1.5 0 0 1 1.5-1.5h15Z'
].map((icon, index) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className={`${index === 2 ? 'size-4' : 'size-3'}`} key={index}>
<path d={icon} />
</svg>
))}
</div>
</div>
{children}
{/* Phone Navigation */}
<div className='absolute rounded-full h-1.5 w-24 bottom-2 left-1/2 transform -translate-x-1/2 bg-neutral-600'></div>
</div>
</>
);
};

const AppHeader = () => {
return (
<div className='flex justify-between items-center pl-2'>
<img
className="size-8 border-2 ring-2 ring-green-500 border-neutral-700 rounded-full cursor-pointer"
src="https://avatars.githubusercontent.com/u/943537?v=4"
alt="Bot Avatar"
/>
<button className='size-8 flex justify-center items-center text-neutral-200 hover:bg-neutral-200/20 rounded-md focus:ring-2 focus:ring-neutral-500 z-50 transition duration-300 ease-in-out'>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-4">
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5M12 17.25h8.25" />
</svg>
</button>
</div>
)
}

const AppNav = ({ active }) => {
return (
<div className='absolute flex items-center justify-between w-full bottom-0 left-1/2 transform -translate-x-1/2 rounded-t-[1.6rem] rounded-b-[1.6rem] pb-6 p-1 gap-1 bg-neutral-700'>
{[
'M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25ZM12.75 6a.75.75 0 0 0-1.5 0v6c0 .414.336.75.75.75h4.5a.75.75 0 0 0 0-1.5h-3.75V6Z',
'M2.625 6.75a1.125 1.125 0 1 1 2.25 0 1.125 1.125 0 0 1-2.25 0Zm4.875 0A.75.75 0 0 1 8.25 6h12a.75.75 0 0 1 0 1.5h-12a.75.75 0 0 1-.75-.75ZM2.625 12a1.125 1.125 0 1 1 2.25 0 1.125 1.125 0 0 1-2.25 0ZM7.5 12a.75.75 0 0 1 .75-.75h12a.75.75 0 0 1 0 1.5h-12A.75.75 0 0 1 7.5 12Zm-4.875 5.25a1.125 1.125 0 1 1 2.25 0 1.125 1.125 0 0 1-2.25 0Zm4.875 0a.75.75 0 0 1 .75-.75h12a.75.75 0 0 1 0 1.5h-12a.75.75 0 0 1-.75-.75Z',
['M12.75 3a.75.75 0 0 1 .75-.75 8.25 8.25 0 0 1 8.25 8.25.75.75 0 0 1-.75.75h-7.5a.75.75 0 0 1-.75-.75V3Z', 'M2.25 13.5a8.25 8.25 0 0 1 8.25-8.25.75.75 0 0 1 .75.75v6.75H18a.75.75 0 0 1 .75.75 8.25 8.25 0 0 1-16.5 0Z'],
'M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z',
].map((nav, index) => (
<button
className={`text-neutral-400 bg-neutral-600/50 flex flex-grow items-center justify-center py-3 rounded-sm hover:bg-neutral-800/10 transition duration-300
${active === 'task' && index === 1 ? '!text-green-500 !bg-neutral-800/50' : ''}
${active === 'timer' && index === 0 ? '!text-green-500 !bg-neutral-800/50' : ''}
${index === 0 ? 'rounded-l-[1.6rem]' : index === 3 ? 'rounded-r-[1.6rem]' : ''}`}
key={index}
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="size-4">
{Array.isArray(nav) ? (
nav.map((d, i) => <path key={i} fillRule="evenodd" clipRule="evenodd" d={d} />)
) : (
<path fillRule="evenodd" clipRule="evenodd" d={nav} />
)}
</svg>
</button>
))}
</div>
)
}

return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<main className="bg-neutral-800">
hello
</main>
<section className="bg-neutral-800 min-h-screen flex items-center justify-center p-12 md:px-12 px-8 py-8">
<div className='flex items-center justify-center md:flex-nowrap flex-wrap gap-12 lg:gap-20'>
{/* First Mockup */}
<PhoneMockup>
<div className='relative h-full px-3.5 pt-12 overflow-hidden'>
{/* Header */}
<AppHeader />
{/* Content */}

{/* Bottom Navigation */}
<AppNav active={'task'} />
</div>
</PhoneMockup>
{/* Second Mockup */}
<PhoneMockup>
<div className='relative h-full px-3.5 pt-12 overflow-hidden'>
{/* Header */}
<AppHeader />
{/* Content */}
<section>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Ut maxime blanditiis rerum, ea animi ipsum laboriosam, sapiente fugiat non esse doloribus quae a nemo recusandae necessitatibus consequatur architecto eos fuga!
</section>

</div>
</PhoneMockup>
</div>
</section>
</motion.div>
)
}
Expand Down

0 comments on commit b79bdf9

Please sign in to comment.