feat: updated some sections

This commit is contained in:
poyrazavsever
2026-07-14 15:48:06 +03:00
parent db3b6930e5
commit 30204be512
12 changed files with 214 additions and 101 deletions
+125 -64
View File
@@ -1,10 +1,18 @@
"use client";
import { Icon } from "@iconify/react";
import Image from "next/image";
import { useRef, useState } from "react";
import { Card, Typography } from "poyraz-ui/atoms";
import { useLocale, useTranslations } from "next-intl";
import { useRouter } from "@/i18n/routing";
import {
Button,
ButtonIcon,
ButtonLabel,
TextEffect,
Typography,
} from "poyraz-ui/atoms";
import { NewsCard } from "poyraz-ui/molecules";
import { useTranslations } from "next-intl";
import { getResumeHref } from "@/lib/links";
type HomeHeroProps = {
news: {
@@ -18,78 +26,131 @@ type HomeHeroProps = {
};
export function HomeHero({ news }: HomeHeroProps) {
const [frame, setFrame] = useState<1 | 2>(1);
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
const t = useTranslations("Home");
const handleMouseEnter = () => {
if (intervalRef.current) return;
intervalRef.current = setInterval(() => {
setFrame((prev) => (prev === 1 ? 2 : 1));
}, 260);
};
const handleMouseLeave = () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
setFrame(1);
};
const locale = useLocale();
const router = useRouter();
return (
<section className="grid gap-3 md:h-65 md:grid-cols-2">
<div className="grid gap-2 md:grid-rows-3">
{news.map((item) => (
<div key={item.id}>
<NewsCard
className="rounded-sm border-border md:h-full"
category={item.category}
title={item.title}
date={item.date}
image={item.image}
href={item.href}
/>
<section className="space-y-4">
<div className="relative grid min-h-[150px] overflow-hidden border-b border-border py-4 sm:grid-cols-[1fr_180px] sm:py-5">
<div className="flex max-w-2xl flex-col justify-center gap-2">
<Typography
variant="h2"
component="h1"
className="leading-none tracking-[-0.045em] font-secondary font-semibold text-foreground text-2xl"
>
Poyraz{" "}
<TextEffect
effect="hand-drawn"
tone="primary"
className="tracking-[-0.04em]"
>
Avsever
</TextEffect>
</Typography>
<Typography
variant="small"
className="max-w-xl text-xs leading-5 text-muted-foreground sm:text-sm"
>
{t("heroDescription")}
</Typography>
<div className="flex flex-wrap items-center gap-2 pt-1">
<Button
type="button"
size="sm"
radius="sm"
effect="swap"
swapTarget="both"
onClick={() => router.push("/contact")}
>
<ButtonLabel>{t("hireMe")}</ButtonLabel>
<ButtonIcon>
<Icon icon="mdi:arrow-right" width={15} height={15} />
</ButtonIcon>
</Button>
<Button
type="button"
variant="secondary"
size="sm"
radius="sm"
effect="swap"
swapTarget="both"
onClick={() => window.open(getResumeHref(locale), "_blank", "noopener,noreferrer")}
>
<ButtonIcon>
<Icon icon="mdi:download" width={15} height={15} />
</ButtonIcon>
<ButtonLabel>{t("downloadCv")}</ButtonLabel>
</Button>
</div>
))}
</div>
<div className="pointer-events-none absolute right-0 bottom-0 hidden h-full w-44 overflow-hidden sm:block">
<Image
src="/images/hero1.png"
alt="Poyraz Avsever"
width={220}
height={220}
sizes="180px"
priority
className="absolute right-0 bottom-0 h-auto w-36 object-contain"
/>
<div
aria-hidden="true"
className="absolute right-0 bottom-0 h-px w-36 bg-border"
/>
</div>
</div>
<Card className="grid grid-cols-[112px_1fr] items-stretch gap-2 rounded-sm border-border sm:grid-cols-[168px_1fr] md:h-full">
<div className="flex flex-col justify-center gap-1 px-3 py-2">
<div className="flex items-center gap-1">
<Typography variant="h2" className="leading-tight">
Poyraz{" "}
<span className="font-secondary text-red-600">Avsever</span>
</Typography>
</div>
<Typography variant="small" className="text-xs leading-relaxed text-muted-foreground sm:text-sm">
{t.rich("role", {
strong: (chunks) => (
<strong className="font-semibold text-foreground">{chunks}</strong>
),
})}
<section className="space-y-3">
<div className="flex items-center justify-between gap-4">
<Typography
variant="h3"
component="h2"
className="tracking-[-0.035em]"
>
{t("readMyPosts")}
</Typography>
<Button
type="button"
size="sm"
radius="sm"
effect="swap"
swapTarget="both"
onClick={() => router.push("/blog")}
>
<ButtonLabel>{t("allPosts")}</ButtonLabel>
<ButtonIcon>
<Icon icon="mdi:arrow-right" width={15} height={15} />
</ButtonIcon>
</Button>
</div>
<div className="relative h-full overflow-hidden">
<div
className="relative h-full w-full"
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<Image
src={frame === 1 ? "/images/hero1.png" : "/images/hero2.png"}
alt="Poyraz Avsever"
width={240}
height={240}
sizes="(max-width: 768px) 80px, 192px"
priority
className="absolute right-0 bottom-0 h-auto w-20 object-contain md:w-48"
/>
<div className="relative overflow-hidden py-1">
<div className="flex w-max items-stretch gap-3">
{news.map((item) => (
<NewsCard
key={item.id}
className="w-72 shrink-0 rounded-sm border-border"
category={item.category}
title={item.title}
date={item.date}
image={item.image}
href={item.href}
/>
))}
</div>
<div
aria-hidden="true"
className="pointer-events-none absolute top-0 right-0 h-full w-24 bg-gradient-to-l from-background via-background/80 to-transparent"
/>
</div>
</Card>
</section>
</section>
);
}
+2 -2
View File
@@ -17,11 +17,11 @@ export function LanguageSwitcher() {
return (
<Button
type="button"
variant="glass"
variant="secondary"
size="icon-sm"
radius="sm"
onClick={toggleLanguage}
className="min-w-9 cursor-pointer !border-border/80 text-xs font-semibold hover:!border-border focus-visible:!border-border"
className="min-w-9 cursor-pointer text-xs font-semibold"
aria-label={locale === "tr" ? "Switch to English" : "Türkçe'ye geç"}
>
{locale === "tr" ? "EN" : "TR"}
+2 -2
View File
@@ -13,7 +13,7 @@ type ReferenceCardsProps = {
export function ReferenceCards({ className, cardClassName, lineClamp }: ReferenceCardsProps) {
const locale = useLocale();
const hoverClassName =
"transition-colors duration-200 group-hover:border-red-600/40 group-hover:bg-muted/30 group-hover:shadow-sm";
"transition-colors duration-200 group-hover:border-red-600/40 group-hover:bg-muted/30";
return (
<div className={className}>
@@ -27,7 +27,7 @@ export function ReferenceCards({ className, cardClassName, lineClamp }: Referenc
role={getLocalizedValue(item.role, locale)}
avatar={item.avatar}
rating={item.rating}
className={`flex flex-col rounded-sm ${lineClamp ? "[&_p]:line-clamp-3" : ""} ${hoverClassName} ${cardClassName || "w-70 shrink-0"}`}
className={`flex flex-col rounded-sm ${lineClamp ? "[&_p]:line-clamp-4" : ""} ${hoverClassName} ${cardClassName || "w-70 shrink-0"}`}
/>
);
+36 -5
View File
@@ -1,24 +1,55 @@
"use client";
import { Icon } from "@iconify/react";
import { ReferenceCards } from "@/components/reference-cards";
import { useRouter } from "@/i18n/routing";
import { Button, ButtonIcon, ButtonLabel, Typography } from "poyraz-ui/atoms";
import { useTranslations } from "next-intl";
export function ReferencesSection() {
const t = useTranslations("Home");
const router = useRouter();
return (
<section className="space-y-8 pt-0 sm:pt-12">
<div className="relative overflow-hidden rounded-sm py-4">
<section className="space-y-3 pt-0 sm:pt-8">
<div className="flex items-center justify-between gap-4">
<Typography
variant="h3"
component="h2"
className="tracking-[-0.035em]"
>
{t("reviewsAndReferences")}
</Typography>
<Button
type="button"
size="sm"
radius="sm"
effect="swap"
swapTarget="both"
onClick={() => router.push("/about/references")}
>
<ButtonLabel>{t("allReferences")}</ButtonLabel>
<ButtonIcon>
<Icon icon="mdi:arrow-right" width={15} height={15} />
</ButtonIcon>
</Button>
</div>
<div className="relative overflow-hidden py-1">
{/* We use two sets of cards for seamless infinite marquee effect */}
<div className="flex items-start w-max gap-4 animate-marquee pause-on-hover">
<div className="flex w-max items-start gap-4 animate-marquee pause-on-hover">
<ReferenceCards className="flex items-start gap-4 shrink-0" lineClamp={true} cardClassName="w-80" />
<ReferenceCards className="flex items-start gap-4 shrink-0" lineClamp={true} cardClassName="w-80" />
</div>
<div
aria-hidden="true"
className="pointer-events-none absolute top-0 right-0 h-full w-32 bg-gradient-to-l from-white to-transparent"
className="pointer-events-none absolute top-0 right-0 h-full w-32 bg-gradient-to-l from-background to-transparent"
/>
<div
aria-hidden="true"
className="pointer-events-none absolute top-0 left-0 h-full w-32 bg-gradient-to-r from-white to-transparent"
className="pointer-events-none absolute top-0 left-0 h-full w-32 bg-gradient-to-r from-background to-transparent"
/>
</div>
</section>
+18 -21
View File
@@ -42,9 +42,6 @@ const SearchCommand = dynamic(
{ ssr: false },
);
const glassActionClassName =
"!border-border/80 hover:!border-border focus-visible:!border-border data-[state=open]:!border-border";
const slowShineClassName = "[--poyraz-motion-duration-deliberate:1100ms]";
function getNavLinkClass(isActive: boolean) {
@@ -85,12 +82,12 @@ function ThemeToggle() {
return (
<Button
type="button"
variant="glass"
variant="secondary"
size="icon-sm"
radius="sm"
effect="shine"
aria-label={label}
className={`cursor-pointer ${glassActionClassName} ${slowShineClassName}`}
className={`cursor-pointer ${slowShineClassName}`}
onClick={() => setTheme(nextTheme)}
>
<Icon
@@ -134,12 +131,12 @@ export function SiteNavbar() {
<TooltipTrigger asChild>
<Button
asChild
variant="glass"
variant="secondary"
size="icon-sm"
radius="sm"
effect="shine"
aria-label={label}
className={`cursor-pointer ${glassActionClassName} ${slowShineClassName}`}
className={`cursor-pointer ${slowShineClassName}`}
>
<a
href={href}
@@ -150,7 +147,7 @@ export function SiteNavbar() {
</a>
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" surface="glass" radius="sm" size="sm">
<TooltipContent side="bottom" surface="soft" radius="sm" size="sm">
{label}
</TooltipContent>
</Tooltip>
@@ -161,7 +158,7 @@ export function SiteNavbar() {
<TooltipTrigger asChild>
<LanguageSwitcher />
</TooltipTrigger>
<TooltipContent side="bottom" surface="glass" radius="sm" size="sm">
<TooltipContent side="bottom" surface="soft" radius="sm" size="sm">
{languageLabel}
</TooltipContent>
</Tooltip>
@@ -170,7 +167,7 @@ export function SiteNavbar() {
<TooltipTrigger asChild>
<ThemeToggle />
</TooltipTrigger>
<TooltipContent side="bottom" surface="glass" radius="sm" size="sm">
<TooltipContent side="bottom" surface="soft" radius="sm" size="sm">
{locale === "tr" ? "Tema değiştir" : "Toggle theme"}
</TooltipContent>
</Tooltip>
@@ -234,11 +231,11 @@ export function SiteNavbar() {
/>
<Button
type="button"
variant="glass"
variant="secondary"
radius="sm"
effect="shine"
onClick={() => setSearchOpen(true)}
className={`h-9 w-44 cursor-pointer justify-between px-3 text-sm sm:w-52 ${glassActionClassName} ${slowShineClassName}`}
className={`h-9 w-44 cursor-pointer justify-between px-3 text-sm sm:w-52 ${slowShineClassName}`}
aria-label={t("search")}
>
<ButtonIcon>
@@ -252,10 +249,10 @@ export function SiteNavbar() {
<DropdownMenuTrigger asChild>
<Button
type="button"
variant="glass"
variant="secondary"
radius="sm"
effect="shine"
className={`h-9 cursor-pointer ${glassActionClassName} ${slowShineClassName}`}
className={`h-9 cursor-pointer ${slowShineClassName}`}
>
<ButtonIcon>
<Icon icon="mdi:share-variant" width={16} height={16} />
@@ -269,7 +266,7 @@ export function SiteNavbar() {
radius="md"
itemSize="md"
itemRadius="sm"
className="w-56 border-border bg-popover"
className="w-56 bg-popover"
>
<DropdownMenuLabel>{t("socialLinks")}</DropdownMenuLabel>
<DropdownMenuSeparator />
@@ -293,11 +290,11 @@ export function SiteNavbar() {
<div className="flex items-center gap-2 md:hidden">
<Button
type="button"
variant="glass"
variant="secondary"
size="icon-sm"
radius="sm"
effect="shine"
className={`cursor-pointer ${glassActionClassName} ${slowShineClassName}`}
className={`cursor-pointer ${slowShineClassName}`}
aria-label={t("search")}
onClick={() => setSearchOpen(true)}
>
@@ -308,10 +305,10 @@ export function SiteNavbar() {
<SheetTrigger asChild>
<Button
type="button"
variant="glass"
variant="secondary"
radius="sm"
effect="shine"
className={`h-9 cursor-pointer ${glassActionClassName} ${slowShineClassName}`}
className={`h-9 cursor-pointer ${slowShineClassName}`}
>
<ButtonIcon>
<Icon icon="mdi:menu" width={18} height={18} />
@@ -325,11 +322,11 @@ export function SiteNavbar() {
<SheetClose asChild>
<Button
type="button"
variant="glass"
variant="secondary"
radius="sm"
effect="shine"
onClick={() => setSearchOpen(true)}
className={`w-full cursor-pointer justify-between ${glassActionClassName} ${slowShineClassName}`}
className={`w-full cursor-pointer justify-between ${slowShineClassName}`}
aria-label={t("search")}
>
<span className="inline-flex items-center gap-2">