Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/kolik/baross/1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/baross/2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/baross/3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/baross/4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/baross/5.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/baross/6.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/bercsenyi/01.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/bercsenyi/02.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/bercsenyi/03.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/bercsenyi/04.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/bercsenyi/05.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/bercsenyi/06.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/bercsenyi/07.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/11.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/12.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/13.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/14.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/17.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/18.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/19.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/kolik/karman/20.png
Binary file added public/kolik/karman/21.png
Binary file added public/kolik/karman/22.jpg
Binary file added public/kolik/karman/3.jpg
Binary file added public/kolik/karman/4.png
Binary file added public/kolik/karman/5.png
Binary file added public/kolik/karman/6.jpg
Binary file added public/kolik/karman/7.png
Binary file added public/kolik/karman/8.png
Binary file added public/kolik/karman/9.png
Binary file added public/kolik/martos/1.jpg
Binary file added public/kolik/martos/2.jpg
Binary file added public/kolik/martos/3.jpg
Binary file added public/kolik/martos/4.jpg
Binary file added public/kolik/martos/5.jpg
Binary file added public/kolik/martos/6.png
Binary file added public/kolik/martos/7.jpg
Binary file added public/kolik/martos/8.jpg
Binary file added public/kolik/sch/1_felezobal.jpg
Binary file added public/kolik/sch/2_golyakocsma.jpg
Binary file added public/kolik/sch/3_schorpong.jpg
Binary file added public/kolik/sch/4_kozeleti_vacsora.jpg
Binary file added public/kolik/sch/6_matrix.jpg
Binary file added public/kolik/sch/7_mmmk.jpg
Binary file added public/kolik/vpk/VPKép1.jpg
Binary file added public/kolik/vpk/VPKép2.jpg
Binary file added public/kolik/vpk/VPKép3.png
Binary file added public/kolik/vpk/VPKép4.png
Binary file added public/kolik/vpk/VPKép5.png
Binary file added public/kolik/vpk/VPKép6.jpg
Binary file added public/kolik/vpk/VPKép7.jpg
Binary file added public/kolik/vpk/VPKép8.jpg
Binary file added public/kolik/vpk/VPKép9.jpg
Binary file added public/kolik/wigner/1.png
Binary file added public/kolik/wigner/2.png
Binary file added public/kolik/wigner/3.jpg
Binary file added public/kolik/wigner/4.jpg
Binary file added public/kolik/wigner/5.jpg
Binary file added public/kolik/wigner/6.jpg
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function DormitoryAdmissionInformationContent({ content }: Readon
{admission_information.capacity_p1}
</p>
<div>
<DormitoryCardsComtainer dormitory={admission_information.dormitory}/>
<DormitoryCardsComtainer dormitory={admission_information.dormitory} linkOrRoute="link"/>
</div>
<p className="text-gray-700 text-lg richtext text-justify">
{admission_information.capacity_p2}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,47 @@
"use client";

import { ImageCard } from "@/components/common/ImageCard";
import { useParams } from "next/navigation";


export default function DormitoryCardsContainer({ dormitory} : Readonly<{ dormitory: string}>) {
export default function DormitoryCardsContainer({ dormitory, linkOrRoute} : Readonly<{ dormitory: string, linkOrRoute: "link" | "route"}>) {
const params = useParams();
const lang = params?.lang ?? "hu";

const imageFolder = "/kolik/"
const baross = {
imageSrc: imageFolder+"baross.jpg",
title: "Baross Gábor "+dormitory,
href: "https://epiteszhk.bme.hu/kollegium/kollegiumaink/baross-gabor-kollegium/"
href: linkOrRoute === "link" ? "https://epiteszhk.bme.hu/kollegium/kollegiumaink/baross-gabor-kollegium/" : `/${lang}/kollegium/kollegium-bemutato/baross`,
}
const bercsenyi = {
imageSrc: imageFolder+"bercsenyi.jpg",
title: "Bercsényi 28-30 "+dormitory,
href: "https://bercsenyi.bme.hu/"
href: linkOrRoute === "link" ? "https://bercsenyi.bme.hu/" : `/${lang}/kollegium/kollegium-bemutato/bercsenyi`
}
const karman = {
imageSrc: imageFolder+"karman.jpg",
title: "Kármán Tódor "+dormitory,
href: "https://ttkhk.bme.hu/koli/karman-2/"
href: linkOrRoute === "link" ? "https://ttkhk.bme.hu/koli/karman-2/" : `/${lang}/kollegium/kollegium-bemutato/karman`,
}
const martos = {
imageSrc: imageFolder+"martos.jpg",
title: "Martos "+dormitory,
href: "https://martos.bme.hu/"
href: linkOrRoute === "link" ? "https://martos.bme.hu/" : `/${lang}/kollegium/kollegium-bemutato/martos`
}
const schonherz = {
imageSrc: imageFolder+"schonherz.jpg",
title: "Schönherz "+dormitory,
href: "https://sch.bme.hu/"
href: linkOrRoute === "link" ? "https://sch.bme.hu/" : `/${lang}/kollegium/kollegium-bemutato/sch`
}
const vasarhelyi = {
imageSrc: imageFolder+"vasarhelyi.jpg",
title: "Vásárhelyi Pál "+dormitory,
href: "https://vpk.bme.hu/"
href: linkOrRoute === "link" ? "https://vpk.bme.hu/" : `/${lang}/kollegium/kollegium-bemutato/vpk`,
}
const wigner = {
imageSrc: imageFolder+"wigner.jpg",
title: "Wigner Jenő "+dormitory,
href: "https://wigner.bme.hu/"
href: linkOrRoute === "link" ? "https://wigner.bme.hu/" : `/${lang}/kollegium/kollegium-bemutato/wigner`
}
return (
<div className="flex flex-col sm:flex-row flex-wrap items-stretch justify-center gap-4 sm:gap-6 flex-1">
Expand Down
166 changes: 166 additions & 0 deletions src/app/(app)/[lang]/kollegium/kollegium-bemutato/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { PageHeader } from "@/components/common/PageHeader";
import { getDictionary } from "@/get-dictionary";
import { Locale } from "@/i18n-config";
import { notFound } from "next/navigation";
import Link from "next/link";
import { ArrowLeft } from "lucide-react";
import fs from "fs";
import path from "path";

const validSlugs = ["baross", "bercsenyi", "karman", "martos", "sch", "vpk", "wigner"] as const;
type DormitorySlug = typeof validSlugs[number];

type ContentBlock =
| { type: 'text'; content: string }
| { type: 'images'; indices: number[] };

function getDormitoryImages(slug: DormitorySlug): string[] {
const imagesDir = path.join(process.cwd(), "public", "kolik", slug);
try {
if (!fs.existsSync(imagesDir)) {
return [];
}
const files = fs.readdirSync(imagesDir);
return files
.filter(file => /\.(jpg|jpeg|png|gif|webp)$/i.test(file))
.sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }))
.map(file => encodeURI(`/kolik/${slug}/${file}`));
} catch (e) {
console.error("Failed to read dormitory images directory", e);
return [];
}
}

export async function generateStaticParams() {
return validSlugs.map((slug) => ({
slug,
}));
}

export default async function DormitoryDetailsPage({
params
}: Readonly<{ params: Promise<{ lang: Locale; slug: string }> }>) {
const { lang, slug } = await params;

if (!validSlugs.includes(slug as DormitorySlug)) {
notFound();
}

const typedSlug = slug as DormitorySlug;
const dictionary = await getDictionary(lang);
const detailsDict = dictionary.dormitory_details;
const dormData = detailsDict[typedSlug];
const images = getDormitoryImages(typedSlug);

// Split at (Image) ignoring leading/trailing newlines
const descriptionParts = dormData.description.split(/(?:\r?\n)*\(Image\)(?:\r?\n)*/i);
const embeddedImageCount = Math.min(images.length, descriptionParts.length - 1);
const remainingImages = images.slice(embeddedImageCount);

const blocks: ContentBlock[] = [];
let currentImageGroup: number[] = [];

descriptionParts.forEach((part, idx) => {
const text = part.trim();
if (text) {
if (currentImageGroup.length > 0) {
blocks.push({ type: 'images', indices: currentImageGroup });
currentImageGroup = [];
}
blocks.push({ type: 'text', content: text });
}

if (idx < descriptionParts.length - 1) {
currentImageGroup.push(idx);
}
});

if (currentImageGroup.length > 0) {
blocks.push({ type: 'images', indices: currentImageGroup });
}

return (
<div className="min-h-screen bg-gray-50">
<div className="container mx-auto px-4 py-8">
<Link
href={`/${lang}/kollegium/kollegium-bemutato`}
className="inline-flex items-center text-red-700 hover:text-red-800 font-medium mb-6 transition-colors"
>
<ArrowLeft className="w-4 h-4 mr-2" />
{detailsDict.back_button}
</Link>

<PageHeader title={dormData.title} />

<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-6 md:p-8 mb-8">
<div className="prose prose-lg max-w-none text-gray-700">
{blocks.map((block, bIdx) => {
if (block.type === 'text') {
return (
<p key={bIdx} className="whitespace-pre-line leading-relaxed mb-6">
{block.content}
</p>
);
} else {
return (
<div key={bIdx} className="my-6 md:my-10 flex flex-wrap justify-center gap-6 items-center w-full">
{block.indices.map(imgIdx => (
images[imgIdx] ? (
<img
key={imgIdx}
src={images[imgIdx]}
alt={`${dormData.title} inline image ${imgIdx + 1}`}
className={`rounded-xl shadow-md md:shadow-lg border border-gray-100 object-contain ${
block.indices.length > 1
? "max-w-full sm:max-w-[calc(50%-12px)] md:max-w-[calc(33.333%-16px)] max-h-[40vh]"
: "max-w-full max-h-[60vh]"
}`}
loading="lazy"
/>
) : (
<div key={imgIdx} className={`p-8 md:p-12 bg-gray-50 rounded-xl border border-gray-200 border-dashed text-center text-gray-500 italic text-sm md:text-base ${
block.indices.length > 1
? "max-w-full sm:max-w-[calc(50%-12px)] md:max-w-[calc(33.333%-16px)]"
: "w-full"
}`}>
[ Kép helye: {imgIdx + 1}. kép hiányzik ]
</div>
)
))}
</div>
);
}
})}
</div>
</div>

{remainingImages.length > 0 || images.length === 0 ? (
<div className="mb-4">
<h2 className="text-2xl font-bold text-gray-900 mb-6 border-b pb-2">
{detailsDict.images_title}
</h2>

{remainingImages.length > 0 ? (
<div className="flex flex-wrap justify-center gap-6 items-center">
{remainingImages.map((imgSrc, idx) => (
<div key={idx} className="rounded-lg overflow-hidden shadow-md group bg-white border border-gray-100">
<img
src={imgSrc}
alt={`${dormData.title} image ${embeddedImageCount + idx + 1}`}
className="max-w-full h-auto max-h-[350px] object-contain transition-transform duration-300 group-hover:scale-105"
loading="lazy"
/>
</div>
))}
</div>
) : (
<div className="bg-gray-100 rounded-lg p-8 text-center text-gray-500 italic">
{detailsDict.no_images}
</div>
)}
</div>
) : null}
</div>
</div>
);
}
19 changes: 19 additions & 0 deletions src/app/(app)/[lang]/kollegium/kollegium-bemutato/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { PageHeader } from "@/components/common/PageHeader";
import { getDictionary } from "@/get-dictionary";
import { Locale } from "@/i18n-config";
import DormitoryCardsContainer from "../felveteli-tajekoztato/components/DormitoryCardsContainer";

export default async function AdmissionInformationPage({
params }: Readonly<{ params: Promise<{ lang: Locale }> }>){
const { lang } = await params;
const dictionary = await getDictionary(lang);

return (
<div className="min-h-screen bg-gray-50">
<div className="container mx-auto px-4 py-8">
<PageHeader title={dictionary.dormitories.admission_information.introduction} />
<DormitoryCardsContainer dormitory={dictionary.dormitories.admission_information.dormitory} linkOrRoute="route"/>
</div>
</div>
)
}
2 changes: 1 addition & 1 deletion src/app/(app)/components/navigation-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export function getNavigationItems(lang: string): NavigationItem[] {
href: link("/kollegium/hirek"),
targetBlank: false,
items: [
{ label: t("Bemutató", "Overview"), href: "#", targetBlank: false },
{ label: t("Bemutató", "Overview"), href: "/kollegium/kollegium-bemutato", targetBlank: false },
{ label: t("Felvételi tájékoztató", "Admission Information"),
href: "/kollegium/felveteli-tajekoztato",
targetBlank: false },
Expand Down
3 changes: 2 additions & 1 deletion src/components/common/ImageCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ interface ImageCardProps {

export function ImageCard({ content }: Readonly<{content: ImageCardProps }> ) {
const { href, imageSrc, title, description} = content;
const shouldBeBlank = href.startsWith('http');
return (
<a href={href} target="_blank" rel="noopener noreferrer" className="block w-full sm:w-auto self-stretch">
<a href={href} target={shouldBeBlank ? "_blank" : "_self"} rel={shouldBeBlank ? "noopener noreferrer" : ""} className="block w-full sm:w-auto self-stretch">
<Card className="group hover:shadow-lg transition-all duration-300 hover:-translate-y-1 cursor-pointer w-full sm:w-64 h-full min-h-[17rem] flex flex-col m-0">
<CardContent className="h-full flex flex-col flex-1 p-6">
<div className="flex flex-col items-center md:items-center text-center gap-4 md:gap-0 flex-1">
Expand Down
36 changes: 35 additions & 1 deletion src/dictionaries/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,8 @@
"contacts_p1": "Should you have any questions regarding dormitory accommodation, please contact the relevant Faculty Student Union, which can be reached at the following addresses:",
"contacts_p2": "For general inquiries, feel free to contact us at ",
"contacts_p3": ".",
"dormitory": "Dormitory"
"dormitory": "Dormitory",
"introduction": "Dormitory introduction"
}
},
"faculties": {
Expand Down Expand Up @@ -413,5 +414,38 @@
"location": "Location:",
"opening_hours": "Opening hours:",
"no_results": "There are no active clubs at the moment"
},
"dormitory_details": {
"back_button": "Back to Dormitories",
"images_title": "Image Gallery",
"no_images": "There are currently no images uploaded for this dormitory.",
"baross": {
"title": "Baross Gábor Dormitory",
"description": "A more detailed description of the dormitory will appear here."
},
"bercsenyi": {
"title": "Bercsényi 28-30 Dormitory",
"description": "A more detailed description of the dormitory will appear here."
},
"karman": {
"title": "Kármán Tódor Dormitory",
"description": "A more detailed description of the dormitory will appear here."
},
"martos": {
"title": "Martos Dormitory",
"description": "A more detailed description of the dormitory will appear here."
},
"sch": {
"title": "Schönherz Dormitory",
"description": "A more detailed description of the dormitory will appear here."
},
"vpk": {
"title": "Vásárhelyi Pál Dormitory",
"description": "A more detailed description of the dormitory will appear here."
},
"wigner": {
"title": "Wigner Jenő Dormitory",
"description": "A more detailed description of the dormitory will appear here."
}
}
}
Loading