diff --git a/src/app/ajakava/page.tsx b/src/app/ajakava/page.tsx index ce78a6c..8bd1850 100644 --- a/src/app/ajakava/page.tsx +++ b/src/app/ajakava/page.tsx @@ -1,72 +1,77 @@ "use client"; -import { useState } from "react"; -import { vipnagorgialla } from "@/components/Vipnagorgialla"; -import { scheduleData } from "@/data/timetable"; +import {useState} from "react"; +import {vipnagorgialla} from "@/components/Vipnagorgialla"; +import {scheduleData} from "@/data/timetable"; +import SectionDivider from "@/components/SectionDivider"; const tabs = Object.keys(scheduleData); export default function Timetable() { - const [activeTab, setActiveTab] = useState(tabs[0]); - const schedule = scheduleData[activeTab]; + const [activeTab, setActiveTab] = useState(tabs[0]); + const schedule = scheduleData[activeTab]; - return ( -
-

- Ajakava -

+ return ( +
+
+

+ Ajakava +

- {/* Tab menu */} -
- {tabs.map((tab) => ( - - ))} -
- - {/* Schedule entries */} -
- {schedule.map((item, idx) => ( -
-
- {item.time} -
-
-
- {item.title} -
- {item.description && ( -
- {item.description} + {/* Tab menu */} +
+ {tabs.map((tab) => ( + + ))}
- )} - {item.location && ( -
- {item.location} + + {/* Schedule entries */} +
+ {schedule.map((item, idx) => ( +
+
+ {item.time} +
+
+
+ {item.title} +
+ {item.description && ( +
+ {item.description} +
+ )} + {item.location && ( +
+ {item.location} +
+ )} +
+
+ ))}
- )}
-
- ))} -
-
- ); + + +
+ ); } diff --git a/src/app/kodukord/page.tsx b/src/app/kodukord/page.tsx index 73a380f..68cb8a1 100644 --- a/src/app/kodukord/page.tsx +++ b/src/app/kodukord/page.tsx @@ -3,48 +3,53 @@ import fs from "node:fs"; import path from "node:path"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; -import { vipnagorgialla } from "@/components/Vipnagorgialla"; +import {vipnagorgialla} from "@/components/Vipnagorgialla"; +import SectionDivider from "@/components/SectionDivider"; export const runtime = "nodejs"; // ensure fs is available (not Edge) export const dynamic = "force-static"; // read at build time export default function Page() { - const filePath = path.join(process.cwd(), "src/data", "kodukord.md"); - const content = fs.readFileSync(filePath, "utf8"); + const filePath = path.join(process.cwd(), "src/data", "kodukord.md"); + const content = fs.readFileSync(filePath, "utf8"); - return ( -
- {/* Page title (separate from markdown headings) */} -

- Kodukord -

+ return ( +
+
+ {/* Page title (separate from markdown headings) */} +

+ Kodukord +

-
- ( -

- ), - h2: ({node, ...props}) => ( -

- ), - ol: ({node, ...props}) => ( -
    - ), - ul: ({node, ...props}) => ( -
      - ), - p: ({node, ...props}) => ( -

      - ), - }} - > - {content} - -

-
- ); +
+ ( +

+ ), + h2: ({node, ...props}) => ( +

+ ), + ol: ({node, ...props}) => ( +
    + ), + ul: ({node, ...props}) => ( +
      + ), + p: ({node, ...props}) => ( +

      + ), + }} + > + {content} + +

+
+ + +
+ ); } diff --git a/src/app/messiala/page.tsx b/src/app/messiala/page.tsx index f95322d..c74a105 100644 --- a/src/app/messiala/page.tsx +++ b/src/app/messiala/page.tsx @@ -1,480 +1,485 @@ "use client"; -import { vipnagorgialla } from "@/components/Vipnagorgialla"; +import {vipnagorgialla} from "@/components/Vipnagorgialla"; import * as THREE from "three"; -import { useEffect, useRef, useState } from "react"; -import { EyeClosed, Eye } from "lucide-react"; +import {useEffect, useRef, useState} from "react"; +import {EyeClosed, Eye} from "lucide-react"; +import SectionDivider from "@/components/SectionDivider"; // Define interface for the ref with toggle function interface MountRefCurrent extends HTMLDivElement { - toggleDividers?: (show: boolean) => void; + toggleDividers?: (show: boolean) => void; } export default function Expo() { - const mountRef = useRef(null); - const [hoveredRoom, setHoveredRoom] = useState(null); - const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 }); - const [showDividers, setShowDividers] = useState(true); - - useEffect(() => { - if (!mountRef.current) return; - - // Copy ref to variable to avoid stale closure in cleanup - const mountElement = mountRef.current; - let dividersRef: THREE.Mesh[] = []; - - // Scene setup - const scene = new THREE.Scene(); - scene.background = new THREE.Color(0x0e0f19); - - // Get responsive dimensions - const getResponsiveDimensions = () => { - const container = mountRef.current; - if (!container) return { width: 800, height: 600 }; - - const containerWidth = container.offsetWidth; - const maxWidth = Math.min(containerWidth, 800); - const width = Math.max(maxWidth, 300); // Minimum width - const height = (width * 600) / 800; // Maintain aspect ratio - - return { width, height }; - }; - - const { width, height } = getResponsiveDimensions(); - - // Isometric camera setup with responsive sizing - const aspect = width / height; - const baseFrustumSize = 14; - const frustumSize = width < 600 ? baseFrustumSize * 0.8 : baseFrustumSize; // Smaller frustum for mobile - const camera = new THREE.OrthographicCamera( - (frustumSize * aspect) / -2, - (frustumSize * aspect) / 2, - frustumSize / 2, - frustumSize / -2, - 1, - 1000, - ); - - // Position camera for isometric view - camera.position.set(10, 10, 14); - camera.lookAt(-1.4, 0, 0); - - // Renderer - const renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setSize(width, height); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; - mountElement.appendChild(renderer.domElement); - - // Raycaster for mouse interactions - const raycaster = new THREE.Raycaster(); - const mouse = new THREE.Vector2(); - - // Lighting - const ambientLight = new THREE.AmbientLight(0x404040, 1.2); - scene.add(ambientLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5); - directionalLight.position.set(10, 10, 5); - directionalLight.castShadow = false; - directionalLight.shadow.mapSize.width = 2048; - directionalLight.shadow.mapSize.height = 2048; - scene.add(directionalLight); - - // Room colors and names - const roomColors = [ - 0xff6b35, // Orange - Mänguklubi - 0x4ecdc4, // Turquoise - Baariala - 0xffe66d, // Yellow - EVAL - 0xe74c3c, // Red - Redbull - 0x9b59b6, // Purple - Võitlusmängu ala - 0x3498db, // Blue - Sony - 0x2ecc71, // Green - Chillimisala - ]; - - const roomNames = [ - "Mänguklubi", - "Baariala", - "EVAL", - "Redbull", - "Võitlusmängu ala", - "Sony", - "Chillimisala", - ]; - - // Create individual rooms as rectangles with custom positions - const rooms: THREE.Mesh[] = []; - const roomData: Array<{ - mesh: THREE.Mesh; - name: string; - originalColor: number; - originalScale: THREE.Vector3; - }> = []; - const dividers: THREE.Mesh[] = []; - - // Define rooms with custom positions, sizes and colors - const roomDefinitions = [ - { - width: 7, - height: 0.7, - depth: 3, - x: 2.5, - z: 4, - color: roomColors[0], - name: roomNames[0], - }, // Mänguklubi - // { - // width: 2.5, - // height: 0.7, - // depth: 0.7, - // x: 1, - // z: 0, - // color: roomColors[1], - // name: roomNames[1], - // }, // Baariala - { - width: 1.8, - height: 0.7, - depth: 1.5, - x: 2.5, - z: -3.5, - color: roomColors[2], - name: roomNames[2], - }, // EVAL - { - width: 2.2, - height: 0.7, - depth: 4.5, - x: 5, - z: -2, - color: roomColors[3], - name: roomNames[3], - }, // Redbull - { - width: 3, - height: 0.7, - depth: 1.3, - x: 0, - z: -3.5, - color: roomColors[4], - name: roomNames[4], - }, // Võitlusmängu ala - { - width: 1.8, - height: 0.7, - depth: 1.5, - x: -2.55, - z: -3.5, - color: roomColors[5], - name: roomNames[5], - }, // Sony - { - width: 4, - height: 0.7, - depth: 4, - x: -5.5, - z: -2.3, - color: roomColors[6], - name: roomNames[6], - }, // Chillimisala - ]; - - roomDefinitions.forEach((roomDef) => { - const geometry = new THREE.BoxGeometry( - roomDef.width, - roomDef.height, - roomDef.depth, - ); - const material = new THREE.MeshLambertMaterial({ - color: roomDef.color, - }); - - const room = new THREE.Mesh(geometry, material); - room.position.set(roomDef.x, roomDef.height / 2, roomDef.z); - room.castShadow = true; - room.receiveShadow = true; - room.userData = { name: roomDef.name, originalColor: roomDef.color }; - - scene.add(room); - rooms.push(room); - roomData.push({ - mesh: room, - name: roomDef.name, - originalColor: roomDef.color, - originalScale: room.scale.clone(), - }); - }); - - // Create toggleable room dividers - const createTogglableDivider = ( - width: number, - height: number, - depth: number, - x: number, - z: number, - ) => { - const wallGeometry = new THREE.BoxGeometry(width, height, depth); - const wallMaterial = new THREE.MeshLambertMaterial({ - color: 0x555555, - transparent: true, - opacity: 0, - }); - - const wall = new THREE.Mesh(wallGeometry, wallMaterial); - wall.position.set(x, height / 2, z); - wall.visible = false; - scene.add(wall); - dividers.push(wall); - }; - - // Add strategic dividers between major areas - createTogglableDivider(10, 2, 2, -2.5, 1.5); // Wall between main entrance - createTogglableDivider(2, 2, 2, 5.5, 1.5); // Wall right next to Mänguklubi & Redbull - - // Store dividers reference for later access - dividersRef = [...dividers]; - - // Ground plane - const groundGeometry = new THREE.PlaneGeometry(14, 10.5); - const groundMaterial = new THREE.MeshLambertMaterial({ color: 0xcccccc }); - const ground = new THREE.Mesh(groundGeometry, groundMaterial); - ground.rotation.x = -Math.PI / 2; - ground.position.x = -1.1; - ground.position.y = -0.5; - ground.receiveShadow = true; - scene.add(ground); - - // Second ground plane - const groundGeometry2 = new THREE.PlaneGeometry(2, 7); - const groundMaterial2 = new THREE.MeshLambertMaterial({ - color: 0xcccccc, - }); - const ground2 = new THREE.Mesh(groundGeometry2, groundMaterial2); - ground2.rotation.x = -Math.PI / 2; - ground2.position.x = -12.2; - ground2.position.y = -5; - ground2.receiveShadow = true; - scene.add(ground2); - - // Resize handler - const handleResize = () => { - const { width: newWidth, height: newHeight } = getResponsiveDimensions(); - - // Update camera - const newAspect = newWidth / newHeight; - const newFrustumSize = - newWidth < 600 ? baseFrustumSize * 0.8 : baseFrustumSize; - - camera.left = (newFrustumSize * newAspect) / -2; - camera.right = (newFrustumSize * newAspect) / 2; - camera.top = newFrustumSize / 2; - camera.bottom = newFrustumSize / -2; - camera.updateProjectionMatrix(); - - // Update renderer - renderer.setSize(newWidth, newHeight); - }; - - // Add resize event listener - window.addEventListener("resize", handleResize); - - // Mouse event handlers - const onMouseMove = (event: MouseEvent) => { - const rect = renderer.domElement.getBoundingClientRect(); - mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; - mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; - - // Update mouse position for tooltip - setMousePosition({ x: event.clientX, y: event.clientY }); - - // Update raycaster - raycaster.setFromCamera(mouse, camera); - const intersects = raycaster.intersectObjects(rooms); - - // Reset all rooms to original state - roomData.forEach(({ mesh, originalColor, originalScale }) => { - (mesh.material as THREE.MeshLambertMaterial).color.setHex( - originalColor, + const mountRef = useRef(null); + const [hoveredRoom, setHoveredRoom] = useState(null); + const [mousePosition, setMousePosition] = useState({x: 0, y: 0}); + const [showDividers, setShowDividers] = useState(true); + + useEffect(() => { + if (!mountRef.current) return; + + // Copy ref to variable to avoid stale closure in cleanup + const mountElement = mountRef.current; + let dividersRef: THREE.Mesh[] = []; + + // Scene setup + const scene = new THREE.Scene(); + scene.background = new THREE.Color(0x0e0f19); + + // Get responsive dimensions + const getResponsiveDimensions = () => { + const container = mountRef.current; + if (!container) return {width: 800, height: 600}; + + const containerWidth = container.offsetWidth; + const maxWidth = Math.min(containerWidth, 800); + const width = Math.max(maxWidth, 300); // Minimum width + const height = (width * 600) / 800; // Maintain aspect ratio + + return {width, height}; + }; + + const {width, height} = getResponsiveDimensions(); + + // Isometric camera setup with responsive sizing + const aspect = width / height; + const baseFrustumSize = 14; + const frustumSize = width < 600 ? baseFrustumSize * 0.8 : baseFrustumSize; // Smaller frustum for mobile + const camera = new THREE.OrthographicCamera( + (frustumSize * aspect) / -2, + (frustumSize * aspect) / 2, + frustumSize / 2, + frustumSize / -2, + 1, + 1000, ); - mesh.scale.copy(originalScale); - }); - - if (intersects.length > 0) { - const hoveredMesh = intersects[0].object as THREE.Mesh; - const roomInfo = roomData.find((r) => r.mesh === hoveredMesh); - - if (roomInfo) { - // Apply hover effects - (hoveredMesh.material as THREE.MeshLambertMaterial).color.setHex( - 0xffffff, - ); - hoveredMesh.scale.multiplyScalar(1.02); - setHoveredRoom(roomInfo.name); + + // Position camera for isometric view + camera.position.set(10, 10, 14); + camera.lookAt(-1.4, 0, 0); + + // Renderer + const renderer = new THREE.WebGLRenderer({antialias: true}); + renderer.setSize(width, height); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; + mountElement.appendChild(renderer.domElement); + + // Raycaster for mouse interactions + const raycaster = new THREE.Raycaster(); + const mouse = new THREE.Vector2(); + + // Lighting + const ambientLight = new THREE.AmbientLight(0x404040, 1.2); + scene.add(ambientLight); + + const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5); + directionalLight.position.set(10, 10, 5); + directionalLight.castShadow = false; + directionalLight.shadow.mapSize.width = 2048; + directionalLight.shadow.mapSize.height = 2048; + scene.add(directionalLight); + + // Room colors and names + const roomColors = [ + 0xff6b35, // Orange - Mänguklubi + 0x4ecdc4, // Turquoise - Baariala + 0xffe66d, // Yellow - EVAL + 0xe74c3c, // Red - Redbull + 0x9b59b6, // Purple - Võitlusmängu ala + 0x3498db, // Blue - Sony + 0x2ecc71, // Green - Chillimisala + ]; + + const roomNames = [ + "Mänguklubi", + "Baariala", + "EVAL", + "Redbull", + "Võitlusmängu ala", + "Sony", + "Chillimisala", + ]; + + // Create individual rooms as rectangles with custom positions + const rooms: THREE.Mesh[] = []; + const roomData: Array<{ + mesh: THREE.Mesh; + name: string; + originalColor: number; + originalScale: THREE.Vector3; + }> = []; + const dividers: THREE.Mesh[] = []; + + // Define rooms with custom positions, sizes and colors + const roomDefinitions = [ + { + width: 7, + height: 0.7, + depth: 3, + x: 2.5, + z: 4, + color: roomColors[0], + name: roomNames[0], + }, // Mänguklubi + // { + // width: 2.5, + // height: 0.7, + // depth: 0.7, + // x: 1, + // z: 0, + // color: roomColors[1], + // name: roomNames[1], + // }, // Baariala + { + width: 1.8, + height: 0.7, + depth: 1.5, + x: 2.5, + z: -3.5, + color: roomColors[2], + name: roomNames[2], + }, // EVAL + { + width: 2.2, + height: 0.7, + depth: 4.5, + x: 5, + z: -2, + color: roomColors[3], + name: roomNames[3], + }, // Redbull + { + width: 3, + height: 0.7, + depth: 1.3, + x: 0, + z: -3.5, + color: roomColors[4], + name: roomNames[4], + }, // Võitlusmängu ala + { + width: 1.8, + height: 0.7, + depth: 1.5, + x: -2.55, + z: -3.5, + color: roomColors[5], + name: roomNames[5], + }, // Sony + { + width: 4, + height: 0.7, + depth: 4, + x: -5.5, + z: -2.3, + color: roomColors[6], + name: roomNames[6], + }, // Chillimisala + ]; + + roomDefinitions.forEach((roomDef) => { + const geometry = new THREE.BoxGeometry( + roomDef.width, + roomDef.height, + roomDef.depth, + ); + const material = new THREE.MeshLambertMaterial({ + color: roomDef.color, + }); + + const room = new THREE.Mesh(geometry, material); + room.position.set(roomDef.x, roomDef.height / 2, roomDef.z); + room.castShadow = true; + room.receiveShadow = true; + room.userData = {name: roomDef.name, originalColor: roomDef.color}; + + scene.add(room); + rooms.push(room); + roomData.push({ + mesh: room, + name: roomDef.name, + originalColor: roomDef.color, + originalScale: room.scale.clone(), + }); + }); + + // Create toggleable room dividers + const createTogglableDivider = ( + width: number, + height: number, + depth: number, + x: number, + z: number, + ) => { + const wallGeometry = new THREE.BoxGeometry(width, height, depth); + const wallMaterial = new THREE.MeshLambertMaterial({ + color: 0x555555, + transparent: true, + opacity: 0, + }); + + const wall = new THREE.Mesh(wallGeometry, wallMaterial); + wall.position.set(x, height / 2, z); + wall.visible = false; + scene.add(wall); + dividers.push(wall); + }; + + // Add strategic dividers between major areas + createTogglableDivider(10, 2, 2, -2.5, 1.5); // Wall between main entrance + createTogglableDivider(2, 2, 2, 5.5, 1.5); // Wall right next to Mänguklubi & Redbull + + // Store dividers reference for later access + dividersRef = [...dividers]; + + // Ground plane + const groundGeometry = new THREE.PlaneGeometry(14, 10.5); + const groundMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc}); + const ground = new THREE.Mesh(groundGeometry, groundMaterial); + ground.rotation.x = -Math.PI / 2; + ground.position.x = -1.1; + ground.position.y = -0.5; + ground.receiveShadow = true; + scene.add(ground); + + // Second ground plane + const groundGeometry2 = new THREE.PlaneGeometry(2, 7); + const groundMaterial2 = new THREE.MeshLambertMaterial({ + color: 0xcccccc, + }); + const ground2 = new THREE.Mesh(groundGeometry2, groundMaterial2); + ground2.rotation.x = -Math.PI / 2; + ground2.position.x = -12.2; + ground2.position.y = -5; + ground2.receiveShadow = true; + scene.add(ground2); + + // Resize handler + const handleResize = () => { + const {width: newWidth, height: newHeight} = getResponsiveDimensions(); + + // Update camera + const newAspect = newWidth / newHeight; + const newFrustumSize = + newWidth < 600 ? baseFrustumSize * 0.8 : baseFrustumSize; + + camera.left = (newFrustumSize * newAspect) / -2; + camera.right = (newFrustumSize * newAspect) / 2; + camera.top = newFrustumSize / 2; + camera.bottom = newFrustumSize / -2; + camera.updateProjectionMatrix(); + + // Update renderer + renderer.setSize(newWidth, newHeight); + }; + + // Add resize event listener + window.addEventListener("resize", handleResize); + + // Mouse event handlers + const onMouseMove = (event: MouseEvent) => { + const rect = renderer.domElement.getBoundingClientRect(); + mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; + mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; + + // Update mouse position for tooltip + setMousePosition({x: event.clientX, y: event.clientY}); + + // Update raycaster + raycaster.setFromCamera(mouse, camera); + const intersects = raycaster.intersectObjects(rooms); + + // Reset all rooms to original state + roomData.forEach(({mesh, originalColor, originalScale}) => { + (mesh.material as THREE.MeshLambertMaterial).color.setHex( + originalColor, + ); + mesh.scale.copy(originalScale); + }); + + if (intersects.length > 0) { + const hoveredMesh = intersects[0].object as THREE.Mesh; + const roomInfo = roomData.find((r) => r.mesh === hoveredMesh); + + if (roomInfo) { + // Apply hover effects + (hoveredMesh.material as THREE.MeshLambertMaterial).color.setHex( + 0xffffff, + ); + hoveredMesh.scale.multiplyScalar(1.02); + setHoveredRoom(roomInfo.name); + } + } else { + setHoveredRoom(null); + } + }; + + // Add mouse event listener + renderer.domElement.addEventListener("mousemove", onMouseMove); + + // Animation loop + const animate = () => { + requestAnimationFrame(animate); + + // Gentle floating animation for rooms + rooms.forEach((room, index) => { + const originalY = 0.25; // height / 2 for the room height of 0.5 + const baseY = originalY + Math.sin(Date.now() * 0.001 + index) * 0.05; + + // Maintain current scale while updating Y position + room.position.y = baseY; + }); + + renderer.render(scene, camera); + }; + + animate(); + + // Function to toggle dividers + const toggleDividers = (show: boolean) => { + dividersRef.forEach((divider) => { + divider.visible = show; + (divider.material as THREE.MeshLambertMaterial).opacity = show + ? 0.4 + : 0; + }); + }; + + // Expose toggle function to parent scope + mountElement.toggleDividers = toggleDividers; + + // Cleanup + return () => { + window.removeEventListener("resize", handleResize); + renderer.domElement.removeEventListener("mousemove", onMouseMove); + if (mountElement && renderer.domElement) { + mountElement.removeChild(renderer.domElement); + } + renderer.dispose(); + }; + }, []); + + // Update dividers when showDividers state changes + useEffect(() => { + if (mountRef.current?.toggleDividers) { + mountRef.current.toggleDividers(showDividers); } - } else { - setHoveredRoom(null); - } - }; - - // Add mouse event listener - renderer.domElement.addEventListener("mousemove", onMouseMove); - - // Animation loop - const animate = () => { - requestAnimationFrame(animate); - - // Gentle floating animation for rooms - rooms.forEach((room, index) => { - const originalY = 0.25; // height / 2 for the room height of 0.5 - const baseY = originalY + Math.sin(Date.now() * 0.001 + index) * 0.05; - - // Maintain current scale while updating Y position - room.position.y = baseY; - }); - - renderer.render(scene, camera); - }; - - animate(); - - // Function to toggle dividers - const toggleDividers = (show: boolean) => { - dividersRef.forEach((divider) => { - divider.visible = show; - (divider.material as THREE.MeshLambertMaterial).opacity = show - ? 0.4 - : 0; - }); - }; - - // Expose toggle function to parent scope - mountElement.toggleDividers = toggleDividers; - - // Cleanup - return () => { - window.removeEventListener("resize", handleResize); - renderer.domElement.removeEventListener("mousemove", onMouseMove); - if (mountElement && renderer.domElement) { - mountElement.removeChild(renderer.domElement); - } - renderer.dispose(); - }; - }, []); - - // Update dividers when showDividers state changes - useEffect(() => { - if (mountRef.current?.toggleDividers) { - mountRef.current.toggleDividers(showDividers); - } - }, [showDividers]); - - return ( -
-

- Messiala -

-
-

- Tudengimaja -

-
-
-
- + }, [showDividers]); + + return ( +
+
+

+ Messiala +

+
+

+ Tudengimaja +

+
+
+
+ Mänguklubi -
-
-
- +
+
+
+ Baariala -
-
-
- +
+
+
+ EVAL -
-
-
- +
+
+
+ Redbull -
-
-
- +
+
+
+ Võitlusmängu ala -
-
-
- +
+
+
+ Sony -
-
-
- +
+
+
+ Chillimisala -
+
+
+
+
+
+ +
+
+ + {/* Tooltip */} + {hoveredRoom && ( +
+ {hoveredRoom} +
+ )} +
+
+ +
-
-
-
- -
-
- - {/* Tooltip */} - {hoveredRoom && ( -
- {hoveredRoom} -
- )} -
-
- ); + ); } diff --git a/src/app/piletid/page.tsx b/src/app/piletid/page.tsx index 4707f69..63da5c6 100644 --- a/src/app/piletid/page.tsx +++ b/src/app/piletid/page.tsx @@ -1,96 +1,105 @@ -import { vipnagorgialla } from "@/components/Vipnagorgialla"; +import {vipnagorgialla} from "@/components/Vipnagorgialla"; import Link from "next/link"; +import SectionDivider from "@/components/SectionDivider"; export default function Tickets() { - return ( -
-

- PILETID JA REGIS­TREERIMINE -

-
-
-

- 8€ -

-

- Arvutiga osaleja -

-
    -
  • - Isiklik laud, voolu- ja internetiühendus -
  • -
  • Ligipääs demoalale
  • -
  • Turniiride pealt vaatamine
  • -
  • Võimalus osaleda miniturniiridel
  • -
- - - -
-
-

- 12-15€ -

-

- Võistleja -

-
    -
  • Võimalus osaleda CS2 või LoL turniiril
  • -
  • - Isiklik laud, voolu- ja internetiühendus -
  • -
  • Ligipääs demoalale
  • -
  • Turniiride pealt vaatamine
  • -
  • Võimalus osaleda miniturniiridel
  • -
- - - -
+ return ( +
+
+

+ PILETID JA REGIS­TREERIMINE +

+
+
+

+ 8€ +

+

+ Arvutiga osaleja +

+
    +
  • + Isiklik laud, voolu- ja internetiühendus +
  • +
  • Ligipääs demoalale
  • +
  • Turniiride pealt vaatamine
  • +
  • Võimalus osaleda miniturniiridel
  • +
+ + + +
+
+

+ 12-15€ +

+

+ Võistleja +

+
    +
  • Võimalus osaleda CS2 või LoL turniiril
  • +
  • + Isiklik laud, voolu- ja internetiühendus +
  • +
  • Ligipääs demoalale
  • +
  • Turniiride pealt vaatamine
  • +
  • Võimalus osaleda miniturniiridel
  • +
+ + + +
-
-

- 6€ -

-

- Külastaja -

-
    -
  • Ligipääs demoalale
  • -
  • Turniiride pealt vaatamine
  • -
  • Võimalus osaleda miniturniiridel
  • -
- - - +
+

+ 6€ +

+

+ Külastaja +

+
    +
  • Ligipääs demoalale
  • +
  • Turniiride pealt vaatamine
  • +
  • Võimalus osaleda miniturniiridel
  • +
+ + + +
+
+
+ +
-
-
- ); + ); } diff --git a/src/app/reeglid/[slug]/page.tsx b/src/app/reeglid/[slug]/page.tsx index 843905f..5e4f735 100644 --- a/src/app/reeglid/[slug]/page.tsx +++ b/src/app/reeglid/[slug]/page.tsx @@ -1,44 +1,49 @@ -import { vipnagorgialla } from "@/components/Vipnagorgialla"; +import {vipnagorgialla} from "@/components/Vipnagorgialla"; import path from "node:path"; import fs from "node:fs/promises"; import ReactMarkdown from "react-markdown"; +import SectionDivider from "@/components/SectionDivider"; type Props = { - params: Promise<{ slug: string }>; + params: Promise<{ slug: string }>; }; -export default async function RulePage({ params }: Props) { - const { slug } = await params; - - const filePath = path.join(process.cwd(), "src/data/rules", `${slug}.md`); - let file: string; - - try { - file = await fs.readFile(filePath, "utf8"); - } catch { - file = `# ${slug.toUpperCase()} REEGLID\n\nSisu hetkel puudub.`; - } - - const data = { title: undefined as string | undefined }; - - return ( - <> -

- {data.title || `${slug.toUpperCase()} REEGLID`} -

- -
- {file} -
- - ); +export default async function RulePage({params}: Props) { + const {slug} = await params; + + const filePath = path.join(process.cwd(), "src/data/rules", `${slug}.md`); + let file: string; + + try { + file = await fs.readFile(filePath, "utf8"); + } catch { + file = `# ${slug.toUpperCase()} REEGLID\n\nSisu hetkel puudub.`; + } + + const data = {title: undefined as string | undefined}; + + return ( + <> +
+

+ {data.title || `${slug.toUpperCase()} REEGLID`} +

+ +
+ {file} +
+
+ + + + ); } diff --git a/src/app/reeglid/page.tsx b/src/app/reeglid/page.tsx index 9339faf..4afaf1e 100644 --- a/src/app/reeglid/page.tsx +++ b/src/app/reeglid/page.tsx @@ -1,5 +1,6 @@ import {vipnagorgialla} from "@/components/Vipnagorgialla"; import Link from "next/link"; +import SectionDivider from "@/components/SectionDivider"; export default function RulesMenu() { const headingStyle = `text-5xl sm:text-6xl ${vipnagorgialla.className} font-bold italic text-[#2A2C3F] dark:text-[#EEE5E5]`; @@ -8,7 +9,7 @@ export default function RulesMenu() { const boxTextStyle = `text-3xl ${vipnagorgialla.className} font-bold uppercase text-[#EEE5E5] pb-2`; - const SectionDivider = () =>
; + // const SectionDivider = () =>
; return (
diff --git a/src/app/turniirid/page.tsx b/src/app/turniirid/page.tsx index a254a60..dfaa889 100644 --- a/src/app/turniirid/page.tsx +++ b/src/app/turniirid/page.tsx @@ -1,11 +1,12 @@ import { vipnagorgialla } from "@/components/Vipnagorgialla"; import Link from "next/link"; import Image from "next/image"; +import SectionDivider from "@/components/SectionDivider"; export default function Tourney() { const headingStyle = `text-3xl md:text-5xl lg:text-5xl ${vipnagorgialla.className} font-bold uppercase text-[#2A2C3F] dark:text-[#EEE5E5] -skew-x-2 md:-skew-x-5`; - const SectionDivider = () =>
; + // const SectionDivider = () =>
; return (
@@ -74,8 +75,7 @@ export default function Tourney() {
- - + {/* LoL turniir */}
diff --git a/src/components/SectionDivider.tsx b/src/components/SectionDivider.tsx new file mode 100644 index 0000000..dc88b17 --- /dev/null +++ b/src/components/SectionDivider.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +export default function SectionDivider() { + return ( +
+ ); +};