Skip to content

Commit

Permalink
Merge pull request #279 from 0x74h51N/Staging
Browse files Browse the repository at this point in the history
hero img fix - explanations - optimizations
  • Loading branch information
0x74h51N authored Aug 23, 2024
2 parents 9b9f911 + 7a3412f commit 233ec38
Show file tree
Hide file tree
Showing 23 changed files with 226 additions and 333 deletions.
201 changes: 39 additions & 162 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Introduction

This project began with the goal of creating a personal website to showcase my skills and portfolio. I have chosen "CrunchyPix" as the website and brand name. This website supports multiple languages through i18n and was built from scratch using Next.js 14. Although Tailwind CSS and DaisyUI are used for styling, the site also includes custom UI elements and components, such as [Dropdown](/components/buttons/Dropdown.tsx) or [Acordiona](/app/about/components/Accordiona.tsx). Localization is handled both on the [server](/i18n/server.ts) and [client](/i18n/client.ts) sides[\*](/i18n/settings.ts), without relying on routing, by configuring i18n on the server to detect and set the language based on the user's browser or referrer information. Third-party services like Cloudinary, Supabase, and Vercel Analytics / SpeedInsight have been integrated, ensuring that Vercel Analytics or SpeedInsight are not activated without user consent, and no personal information is collected without permission.
This project began with the goal of creating a personal website to showcase my skills and portfolio. I have chosen "CrunchyPix" as the website and brand name. This website supports multiple languages through i18n and was built from scratch using Next.js 14. Although Tailwind CSS and DaisyUI are used for styling, the site also includes custom UI elements and components. Localization is handled both on the [server](/i18n/server.ts) and [client](/i18n/client.ts) sides[\*](/i18n/settings.ts), without relying on routing, by configuring i18n on the server to detect and set the language based on the user's browser or referrer information. Third-party services like Cloudinary, Supabase, and Vercel Analytics / SpeedInsight have been integrated, ensuring that Vercel Analytics or SpeedInsight are not activated without user consent, and no personal information is collected without permission.

## 📦 Technology Stack

Expand Down Expand Up @@ -61,172 +61,50 @@ This project began with the goal of creating a personal website to showcase my s
## 🗃️ Directory

```
├── LICENSE.md
├── README.md
├── app
│ ├── about
│ │ ├── components
│ │ └── page.tsx
│ ├── actions
│ │ └── sendMailAction.ts
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ ├── not-found.tsx
│ ├── page.tsx
│ ├── policies
│ ├── actions # Contains server-side actions for validating and processing user inputs.
│ ├── about # About page, includes components and dynamically generated subpages.
│ │ └── components # Specific components used within the About page.
│ ├── policies # Policies page, with components and dynamic subpages for each policy ([id]).
│ │ └── [id]
│ └── portfolio
│ │ └── components # Components related to individual policy subpages.
│ └── portfolio # Portfolio page, includes components and dynamically generated subpages.
│ ├── [id]
│ ├── components
│ ├── layout.tsx
│ └── page.tsx
│ │ └── components # Components for individual portfolio items' subpages.
│ └── components # General components used within the Portfolio page.
├── components
│ ├── Buttons
│ │ ├── ArrowButton.tsx
│ │ ├── ArrowSVG.tsx
│ │ ├── ArrowToTop.tsx
│ │ ├── BurgerButton.tsx
│ │ ├── CancelButton.tsx
│ │ ├── Dropdown.tsx
│ │ └── IconButton.tsx
│ ├── CardMaker.tsx
│ ├── ColorfulBorder.tsx
│ ├── ColorfulHover.tsx
│ ├── Construction.tsx
│ ├── Cookies
│ │ ├── Cookies.tsx
│ │ └── CookiesConsent.tsx
│ ├── CustomCursor.tsx
│ ├── CustomLink.tsx
│ ├── Footer
│ │ ├── Captcha.tsx
│ │ ├── Contact.tsx
│ │ ├── Footer.tsx
│ │ └── FooterColumn.tsx
│ ├── Frames
│ │ ├── MonitorFrame
│ │ └── PhoneFrame
│ ├── GenerateSpans.tsx
│ ├── Labels.tsx
│ ├── Loading
│ │ ├── FsLoading.tsx
│ │ └── Loading.tsx
│ ├── LogoImage.tsx
│ ├── Navbar
│ │ ├── CrunchyLogo.tsx
│ │ ├── LanguageMenu.tsx
│ │ ├── MobileMenu.tsx
│ │ └── Navbar.tsx
│ ├── PortfolioDataStore.tsx
│ ├── RooteTitles
│ │ ├── AllRoutes.tsx
│ │ ├── MainRoutes.tsx
│ │ ├── SubRoutes.tsx
│ │ └── checkIfPageExist.ts
│ ├── Sections
│ │ ├── CodeSect
│ │ ├── DesignSect
│ │ ├── IntroductionSect
│ │ ├── LandingSect
│ │ ├── LogoSection
│ │ ├── PortfolioSect
│ │ ├── Section.tsx
│ │ ├── ServicesSect
│ │ └── TitleText.tsx
│ ├── Slider
│ │ ├── FullScreenSlider
│ │ ├── LogoSlide.tsx
│ │ └── Portfolio
│ ├── SocialIcons.tsx
│ ├── SvgAnimator.tsx
│ └── typeText.tsx
├── constants
│ ├── codeString.ts
│ ├── colorPacks.ts
│ ├── index.ts
│ ├── phoneSlides.ts
│ ├── policyDatas.ts
│ └── sections.tsx
├── global.d.ts
├── hooks
│ ├── useBlurUrl.ts
│ ├── useClickableHandlers.ts
│ ├── useDragHandler.ts
│ ├── useFilteredData.ts
│ ├── useIntersectionObserver.ts
│ ├── useOutsideClick.ts
│ ├── useSupabaseFetch.ts
│ ├── useThrottle.ts
│ └── useTranslation.ts
├── i18n
│ ├── actions
│ │ └── switch-locale.ts
│ ├── client.ts
│ ├── i18Provider.tsx
│ ├── locales
│ │ ├── de
│ │ ├── en
│ │ └── tr
│ ├── resourcesToBackend.ts
│ ├── server.ts
│ └── settings.ts
│ ├── Buttons # Contains various buttons used across the site.
│ ├── Cookies # Manages user consent for enabling Vercel Analytics and Speedinsight.
│ ├── Footer # The footer component for the site, typically includes site links and credits.
│ ├── Frames # Contains components for displaying monitor and phone frames with embedded content.
│ ├── Loading # Components that display loading animations or placeholders.
│ ├── Navbar # The site's main navigation bar component.
│ ├── RootTitles # Displays the current page or subsection title, used on pages other than the homepage.
│ ├── Sections # Components that define different sections of the homepage.
│ │ ├── CodeSect # Section focused on coding or development content.
│ │ ├── DesignSect # Section related to design content.
│ │ ├── IntroductionSect # The introduction section of the homepage.
│ │ ├── LandingSect # Landing section, typically the first visible section on the homepage.
│ │ ├── LogoSection # Displays logos or branding elements.
│ │ ├── PortfolioSect # Section showcasing portfolio items.
│ │ └── ServicesSect # Section outlining the services offered.
│ └── Slider
│ ├── FullScreenSlider # A slider component that adjusts to the size of the parent div, creating full-screen slides.
│ └── Portfolio # Contains a Carousel slider for portfolio items with Modal components for detailed views.
├── constants # Stores constant values used throughout the application.
├── hooks # Contains custom React hooks for managing state and side effects.
├── i18n # Contains i18next settings, providers, server and client side functions.
│ ├── actions # Actions related to internationalization (i18n).
│ └── locales # Contains translation files and locale-specific data.
├── lib
│ ├── metadata.ts
│ ├── metadataSub.ts
│ ├── supabaseClient.ts
│ └── utils
│ ├── cache.ts
│ ├── fetchSupabaseData.ts
│ └── filterByLanguage.ts
├── middleware.ts
├── next-env.d.ts
├── next.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ ├── LogoL.svg
│ ├── arrow.svg
│ ├── fonts
│ │ └── britannic-bold
│ ├── logo.svg
│ ├── logoRight.svg
│ ├── logo_L.svg
│ ├── logo_leftw.svg
│ ├── ogImage.avif
│ ├── phone.svg
│ ├── projectInfo.png
│ └── rotateArrow.svg
├── schemas
│ └── index.ts
│ └── utils # General utility functions used across the application.
├── public # Public assets, such as images and fonts, accessible by the browser.
├── schemas # Defines schemas for data validation or database models.
├── store
│ ├── index.ts
│ ├── provider.tsx
│ └── redux
│ ├── cookieConsent.ts
│ ├── cursorDisabled.ts
│ ├── isClickable.ts
│ ├── isScrollEnabled.ts
│ ├── isSlider.ts
│ ├── isTouch.ts
│ ├── pageReducer.ts
│ ├── portfolioItems.ts
│ ├── sectionItems.ts
│ └── selectedSlide.ts
├── tailwind.config.ts
├── tsconfig.json
├── types
│ ├── common.types.ts
│ └── turnstile.d.ts
└── utils
├── getRandomColor.ts
├── handleScroll.ts
├── logoComponent.ts
├── motion.ts
├── randomColors.ts
├── scrollEventControl.ts
└── scrollToSection.ts
│ └── redux # Redux store configuration and related files.
├── types # TypeScript type definitions used throughout the project.
└── utils # Miscellaneous utility functions and helpers.
```

## License
Expand Down Expand Up @@ -266,4 +144,3 @@ npm run start
```

- Open [http://localhost:3000](http://localhost:8080)

4 changes: 2 additions & 2 deletions app/about/components/AboutMe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ const AboutMe = () => {
)}
<div
data-tip={t('page.mode')}
className="self-start h-12 relative mb-4 w-[152px] pr-4 z-20 transform brightness-100 hover:brightness-150 transition-brightness ease-in-out duration-500 tooltip tooltip-right"
className="self-start h-12 relative mb-4 w-[152px] pr-4 z-20 transform brightness-100 hover:brightness-150 transition-brightness ease-in-out duration-500 tooltip tooltip-right before:bg-nav-col"
>
<Dropdown
setSelectedOption={setSelectedOption}
Expand Down Expand Up @@ -166,7 +166,7 @@ const AboutMe = () => {
<>
<h3
data-tip={t('page.faqsLong')}
className="h3 mt-20 self-start tooltip tooltip-top before:left-16 before:bg-nav-col"
className="h3 mt-20 self-start tooltip tooltip-top before:left-20 before:bg-nav-col"
>
{t('page.faqs')}
</h3>
Expand Down
4 changes: 4 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -464,3 +464,7 @@ input,
button {
cursor: none !important;
}

.tooltip-crunchy {
@apply before:text-white before:text-xs before:bg-cool-gray-700 before:border-[1px] before:py-0.5 before:border-nav-col after:text-nav-col;
}
4 changes: 2 additions & 2 deletions app/portfolio/[id]/components/Project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const Project = memo(({ id }: { id: string }) => {
whileInView="show"
viewport={{ once: true, amount: 'some' }}
variants={polygonIn('screen', 'easeInOut', 0, 0)}
className="flex flex-col items-center h-full w-full max-w-[1300px] min-h-[100svh] md:py-20 py-14 px-8 delay-700 duration-1000"
className="flex flex-col items-center h-full w-full max-w-[1300px] min-h-[100svh] md:py-20 py-14 sm:px-8 px-4 delay-700 duration-1000"
>
<TopImage id={Item.project_id} icons={iconsArray} />
<motion.div
Expand Down Expand Up @@ -136,7 +136,7 @@ const Project = memo(({ id }: { id: string }) => {
whileInView="show"
viewport={{ once: true, amount: 'some' }}
variants={polygonIn('down', 'spring', 1.2, 2)}
className="lg:w-2/3 sm:w-full w-auto xl:pr-0 lg:pr-24 max-sm:mb-6"
className="lg:w-2/3 sm:w-full w-auto xl:pr-0 lg:pr-24 max-sm:mb-6 max-sm:ml-6"
>
<Ticks ticks={Item.ticks} />
</motion.div>
Expand Down
4 changes: 2 additions & 2 deletions app/portfolio/[id]/components/ProjectInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ const ProjectInfo = ({
<div className="absolute left-0 lg:bottom-12 md:bottom-8 sm:bottom-12 bottom-8 flex flex-row justify-between p-2 lg:px-[4.2rem] md:px-12 px-10 bg-slate-300 bg-opacity-50 w-full ">
{Tech.map((tech, index) => (
<div
key={index}
className="relative md:w-10 md:h-10 w-7 h-7 grayscale"
key={index + ' key ' + tech}
className="flex md:w-10 md:h-10 w-7 h-7 grayscale"
>
<LogoImage logoKey={tech} index={index} />
</div>
Expand Down
8 changes: 4 additions & 4 deletions app/portfolio/[id]/components/TopImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const TopImage = ({ id, icons }: { id: string; icons?: IconProps[] }) => {
imageTop.includes('catalog')
? 'lg:min-h-[870px] md:min-h-[700px]'
: 'md:min-h-[700px]'
} md:min-h-[400px] min-h-[650px]`}
} md:min-h-[400px] min-h-[630px]`}
style={{
backgroundImage: imageTop.includes('kyk')
? 'linear-gradient(to bottom right, #e2e8f0, #d6d3d1)'
Expand All @@ -61,7 +61,7 @@ const TopImage = ({ id, icons }: { id: string; icons?: IconProps[] }) => {
<CldImage
fill
quality={5}
blur={"250"}
blur={'250'}
src={mobile ? imageMobile : imageTop}
alt={id}
className={`w-full h-full object-cover transition-opacity ease-in-out duration-300 `}
Expand All @@ -71,7 +71,7 @@ const TopImage = ({ id, icons }: { id: string; icons?: IconProps[] }) => {
(icons.length > 0 ? (
<motion.div
variants={slideIn('right', 'spring', 2, 1)}
className="absolute flex flex-row gap-4 bottom-5 py-3 right-0 pr-7 pl-4 bg-black bg-opacity-50 rounded-l-lg"
className="absolute flex flex-row sm:gap-4 gap-3 bottom-5 sm:py-3 py-2 sm:right-0 -right-3 pr-7 pl-4 bg-black bg-opacity-50 rounded-l-lg"
>
{icons
.sort((a, b) => a.id - b.id)
Expand All @@ -82,7 +82,7 @@ const TopImage = ({ id, icons }: { id: string; icons?: IconProps[] }) => {
Live
</span>
)}
<span className="hover:text-log-col transition-all ease-in-out duration-300 text-cool-gray-50 lg:text-4xl text-3xl hover:scale-110">
<span className="flex hover:text-log-col transition-all ease-in-out duration-300 text-cool-gray-50 lg:text-4xl text-3xl hover:scale-110">
<IconButton key={iconIndex} icon={icon} />
</span>
</div>
Expand Down
19 changes: 11 additions & 8 deletions components/Buttons/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,24 @@ const iconComponents: { [key: string]: IconType } = {
freecodecamp: FaFreeCodeCamp,
};

const IconButton = ({ icon, size }: { icon: IconProps; size?: number }) => {
const IconButton = ({
icon,
size,
tooltipDirection = 'top',
}: {
icon: IconProps;
size?: number;
tooltipDirection?: string;
}) => {
const iconType = icon.type && icon.type.toLowerCase();
const IconComponent = icon.type && iconType && iconComponents[iconType];
const { handleMouseEnter, handleMouseLeave } = useClickableHandlers();

if (iconType && IconComponent) {
return (
<div
className="relative group cursor-none"
data-tip={icon.alt}
className={`cursor-none tooltip tooltip-${tooltipDirection} tooltip-crunchy`}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
Expand All @@ -94,12 +103,6 @@ const IconButton = ({ icon, size }: { icon: IconProps; size?: number }) => {
size={icon.size ? icon.size : size}
color={icon.color}
/>

{icon.alt && (
<span className="absolute self-center rounded-md border-spacing-1 border-cool-gray-700 border-2 w-auto p-[2px] text-center text-white text-xs bg-cool-gray-400 opacity-0 transition-opacity group-hover:opacity-80 ease-in-out duration-300 pointer-events-none cursor-none whitespace-nowrap">
{icon.alt}
</span>
)}
</a>
</div>
);
Expand Down
Loading

0 comments on commit 233ec38

Please sign in to comment.