Skip to content
Merged
2 changes: 1 addition & 1 deletion src/app/(frontend)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default async function RootLayout(props: { children: React.ReactNode }) {
<html lang="en">
<body>
<Header />
<main className="text-red-500">{children}</main>
<main>{children}</main>
<Footer />
</body>
</html>
Expand Down
49 changes: 27 additions & 22 deletions src/app/(frontend)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import './styles.css'
import BlogsBlock from '../components/BlogsBlock'
import Grid from './components/Grid'
import AnnualReports from './components/AnnualReports'

Expand All @@ -15,32 +16,36 @@ export default function HomePage() {
<h1 className="text-heading font-semibold">Heading</h1>
<div className="text-muted">Muted Text</div>

<div className="mt-5 text-[20] leading-body">
<p>
Auckland Youth Orchestra is the premier regional youth orchestra in New Zealand. Founded
in 1948, and originally named the Auckland Junior Symphony Orchestra (or AJSO), it was
the first youth orchestra established in the Southern Hemisphere. It is designed to
bridge the gap between school orchestras and adult professional groups.
</p>
</div>
<div className="mt-5 text-[20] leading-body">
<p>
Auckland Youth Orchestra is the premier regional youth orchestra in New Zealand.
Founded in 1948, and originally named the Auckland Junior Symphony Orchestra (or
AJSO), it was the first youth orchestra established in the Southern Hemisphere. It is
designed to bridge the gap between school orchestras and adult professional groups.
</p>
</div>

<div className="mt-5 text-body leading-body">
<p>
This is standard body text. The Final of the 2025 AYO Soloist Competition was held on
Sunday, 19 October 2025.  It was an exciting event with the wonderful talent of AYO’s
players being showcased once more.
</p>
</div>
<div className="mt-5 text-body leading-body">
<p>
This is standard body text. The Final of the 2025 AYO Soloist Competition was held on
Sunday, 19 October 2025.  It was an exciting event with the wonderful talent of AYO’s
players being showcased once more.
</p>
</div>

<div className="mt-5 text-body leading-miniheader">
<p className="font-semibold">AYO Soloist Competition</p>
<p>
{' '}
This is the line spacing for card components. Apply by 15th of August, 11:59pm
NZST.{' '}
</p>
<div className="mt-5 text-body leading-miniheader">
<p className="font-semibold">AYO Soloist Competition</p>
<p>
{' '}
This is the line spacing for card components. Apply by 15th of August, 11:59pm
NZST.{' '}
</p>
</div>
</div>
</div>
<div>
<BlogsBlock />
</div>
</div>
)
}
94 changes: 94 additions & 0 deletions src/app/components/BlogsBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
'use client'

import { useState } from 'react'
import Link from 'next/link'

import BlogsCard from './BlogsCard'
import BlogsFilter from './BlogsFilter'
import BlogsPagination from './BlogsPagination'

export default function BlogsBlock() {
// Dummy data for now, to be replaced with real data from backend
const DummyBlogs = [
{
id: 1,
title: '2025 Soloist Competition',
date: 'November 1st, 2025',
excerpt:
'The Final of the 2025 AYO Soloist Competition was held on Sunday, 19 October 2025.  It was an exciting event with the wonderful talent of AYO’s players being showcased once more.',
},
{
id: 2,
title:
'Hear Tony Yan Tong Chen being interviewed about our June concert series on RNZ Concert',
date: 'June 6th, 2025',
excerpt:
'AYO’s soloist for the June concert series Tony Yan Tong Chen was interviewed by Bryan Crump on RNZ Concert on 4 June 2025 – hear the interview and some of his recordings here!',
},
{
id: 3,
title: 'Update – Howick June Concert CANCELLED',
date: 'June 6th, 2025',
excerpt:
'With less than two weeks to go until the first concert of this series we regret inform you that our popular Howick venue, the All Saints Church, has suffered significant flooding and is...',
},
{
id: 4,
title: 'test blog post 4',
date: 'happy new year',
excerpt: 'A fake blog post.',
},
{
id: 5,
title: 'test blog post 5',
date: 'happy new year',
excerpt: 'A fake blog post.',
},
{
id: 6,
title: 'test blog post 6',
date: 'happy new year',
excerpt: 'A fake blog post.',
},
{
id: 7,
title: 'test blog post 7',
date: 'happy new year',
excerpt: 'A fake blog post.',
},
]

//blogs pagination
const [currentPage, setCurrentPage] = useState(1)

const totalCards = Math.ceil(DummyBlogs.length / 3) // calculate total num of cards for pagination total eg. 1 of {total}

//slicing
const currentBlogs = DummyBlogs.slice((currentPage - 1) * 3, (currentPage - 1) * 3 + 3) // 1-3, 4-6, 7

return (
<div className="px-24 py-14">
<Link href={'/news'}>
{/* TO: Resources page // all News */}
<h1 className="text-4xl font-semibold mb-6 pl-12 hover:text-muted transition-colors">
News
</h1>
</Link>
{/* What's New? // Latest Stories*/}

<BlogsFilter />

<div>
{currentBlogs.map((blog) => (
<BlogsCard key={blog.id} {...blog} />
))}
</div>

<BlogsPagination
currentPage={currentPage}
totalPages={totalCards}
onPageChange={setCurrentPage}
/>
</div>
)
}
33 changes: 33 additions & 0 deletions src/app/components/BlogsCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Link from 'next/link'

type Blog = {
id: number
title: string
date: string
excerpt: string
//image: string
//category: string (disabled for now)
}

export default function BlogsCard(Blog: Blog) {
return (
<Link href={'/news/' + Blog.id}>
<div className="border-t border-[#EBEBEB] lg:grid lg:grid-cols-2 py-12 xl:gap-x-70 md:gap-x-20 sm:gap-x-10 hover:bg-gray-50 transition-colors">
<div className="lg:ml-12 2xl:pr-40 ">
{/*xl:pr-80 lg:pr-8 md:pr-6 sm:pr-4 */}
{/* left column */}

{/*TO: individual blog post page*/}

<h2 className="font-semibold">{Blog.title}</h2>

<p className="mt-2 text-sm mb-6">{Blog.date}</p>
</div>
<div className="lg:flex lg:justify-end lg:mr-20">
{/* xl:mr-20 xl:ml-40 */}
<p className="italic text-[#]">{Blog.excerpt}</p>
</div>
</div>
</Link>
)
}
54 changes: 54 additions & 0 deletions src/app/components/BlogsFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
'use client'
import { useState } from 'react'

const Years = ['2025', '2024', '2023', '2022', '2021']
const Months = [
'All',
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]

{
/*type FilterOption = {
onYearChange: (year: string) => void
onMonthChange: (month: string) => void
}*/
}

export default function BlogsFilter() {
const [selectedYear, setSelectedYear] = useState('2025')
const [selectedMonth, setSelectedMonth] = useState('All')
return (
<div className="flex gap-6 mb-6 lg:pl-12">
<p className="text-muted">Year</p>
<select
value={selectedYear}
onChange={(e) => setSelectedYear(e.target.value)}
className="appearance-none font-semibold hover:text-muted transition-colors"
>
<option value="2025">2025</option>
<option value="2024">2024</option>
</select>
<p className="text-muted">Month</p>
<select
value={selectedMonth}
onChange={(e) => setSelectedMonth(e.target.value)}
className="appearance-none font-semibold hover:text-muted transition-colors"
>
<option value="">All</option>
<option value="November">November</option>
<option value="June">June</option>
</select>
</div>
)
}
37 changes: 37 additions & 0 deletions src/app/components/BlogsPagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use client'
import { useState } from 'react'

type BlogsPaginationProps = {
currentPage: number
totalPages: number
onPageChange: (page: number) => void
}

export default function BlogsPagination({
currentPage,
totalPages,
onPageChange,
}: BlogsPaginationProps) {
return (
<div className="border-t border-[#EBEBEB] pt-5 flex justify-end gap-6 items-center">
{/* border colour is from figma */}
<button
onClick={() => onPageChange(currentPage - 1)}
disabled={currentPage === 1}
className="underline underline-offset-3 hover:text-muted transition-colors"
>
Previous
</button>
<span className="px-6">
{currentPage} of {totalPages}
</span>
<button
onClick={() => onPageChange(currentPage + 1)}
disabled={currentPage === totalPages}
className="underline underline-offset-3 hover:text-muted transition-colors"
>
Next
</button>
</div>
)
}
Loading