Files
kolaytercih/src/components/uni-logo.tsx

117 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Image from "next/image";
import { cn } from "@/lib/utils";
import { uniLogoYolu } from "@/lib/uni-logolar";
import { turkishSlugify } from "@/lib/slug";
/**
* Üniversite logosu; dosyası olmayanlar için ad baş harflerinden monogram.
* Logolar 300×300 PNG (public/uni-logo, kaynak YÖK Atlas) — beyaz zeminli
* kapsayıcı hem şeffaf hem beyaz arka planlı logolarda tutarlı görünür.
*/
const BOYUT: Record<"xs" | "sm" | "md" | "lg", string> = {
xs: "size-7 rounded-md p-0.5",
sm: "size-9 rounded-lg p-1",
md: "size-12 rounded-xl p-1.5",
lg: "size-16 rounded-2xl p-2 sm:size-20",
};
const MONOGRAM_METIN: Record<"xs" | "sm" | "md" | "lg", string> = {
xs: "text-[10px]",
sm: "text-xs",
md: "text-sm",
lg: "text-lg sm:text-xl",
};
// "İstanbul Teknik Üniversitesi" → "İT"; tür sözcükleri baş harfe girmez
const TUR_SOZCUKLERI = new Set([
"üniversitesi",
"üniversite",
"meslek",
"yüksekokulu",
"yüksek",
"okulu",
"ve",
]);
function monogram(ad: string): string {
const harfler = ad
.split(/\s+/)
.filter((w) => w && !TUR_SOZCUKLERI.has(w.toLocaleLowerCase("tr-TR")))
.slice(0, 2)
.map((w) => w[0].toLocaleUpperCase("tr-TR"));
return harfler.join("") || ad.slice(0, 1).toLocaleUpperCase("tr-TR");
}
/**
* Ham DB adından logo yolu: "(İL)" eki atılıp slug'lanır (katalog.ts ile
* aynı anahtar). Haritalar gibi next/image kullanamayan SVG bağlamları için.
*/
export function uniLogoYoluFromAd(ad: string): string | null {
return uniLogoYolu(turkishSlugify(ad.replace(/\s*\([^)]*\)\s*$/, "").trim()));
}
// Slug'dan deterministik pastel ton — aynı üniversite her yerde aynı renk
function tonu(slug: string): number {
let h = 0;
for (let i = 0; i < slug.length; i++) h = (h * 31 + slug.charCodeAt(i)) % 360;
return h;
}
export function UniLogo({
slug,
ad,
boy = "sm",
className,
}: {
/** Verilmezse ham addan türetilir ("(İL)" eki atılıp slug'lanır) */
slug?: string;
ad: string;
boy?: "xs" | "sm" | "md" | "lg";
className?: string;
}) {
const anahtar =
slug ?? turkishSlugify(ad.replace(/\s*\([^)]*\)\s*$/, "").trim());
const yol = uniLogoYolu(anahtar);
const px = boy === "lg" ? 80 : boy === "md" ? 48 : boy === "sm" ? 36 : 28;
if (!yol) {
const h = tonu(anahtar);
return (
<span
aria-hidden="true"
className={cn(
"flex shrink-0 select-none items-center justify-center font-heading font-bold ring-1 ring-inset ring-slate-900/10",
BOYUT[boy],
MONOGRAM_METIN[boy],
className,
)}
style={{
backgroundColor: `oklch(0.95 0.03 ${h})`,
color: `oklch(0.45 0.09 ${h})`,
}}
>
{monogram(ad)}
</span>
);
}
return (
<span
className={cn(
"flex shrink-0 items-center justify-center bg-white ring-1 ring-inset ring-slate-900/10",
BOYUT[boy],
className,
)}
>
<Image
src={yol}
alt={`${ad} logosu`}
width={px}
height={px}
className="size-full object-contain"
/>
</span>
);
}