This commit is contained in:
Philip Cheung 2024-10-06 11:52:45 +08:00
parent ee746cd61d
commit 3272da0b2b
16 changed files with 483 additions and 81 deletions

41
app/aboutus/page.tsx Normal file
View File

@ -0,0 +1,41 @@
import React from 'react'
import ResponsiveNav from "@/components/Navbar/ResponsiveNav";
import { fetchCourses, fetchSettings, fetchAboutus } from "@/utils";
import { CoursesProps, AboutusProps } from "@/types";
import Course from '@/components/Course/Course';
import dynamic from 'next/dynamic'
import Home from '@/components/Aboutus/Home';
async function getCourses() {
const courses = await fetchCourses();
return courses;
}
async function getAboutus() {
const aboutus: AboutusProps[] = await fetchAboutus();
return aboutus;
}
async function getSettings() {
const settings = await fetchSettings();
return settings;
}
export const metadata = {
title: "All In One",
description: "**",
}
export default async function Page({ params }: { params: { slug: string } }) {
const courses = await getCourses();
const settings = await getSettings();
const aboutus = await getAboutus();
//const course = await getCourse(params.slug);
return (
<div className='bg-[#F6E8E9]'>
<ResponsiveNav courses={courses} settings={settings} />
<Home courses={courses} settings={settings} aboutus={aboutus} />
</div>
)
}

View File

@ -37,7 +37,7 @@ export default async function Page({ params }: { params: { slug: string } }) {
return (
<div className='bg-[#F6E8E8]'>
<ResponsiveNav courses={courses} settings={settings} />
<DynamicComponent course={course} />
<DynamicComponent course={course} settings={settings} />
</div>
)
}

View File

@ -0,0 +1,102 @@
import React from 'react'
import { CoursesProps, AboutusProps } from '@/types'
const AboutusContent = ({ aboutus }: { aboutus: AboutusProps[] }) => {
return (
<div className='relative flex flex-col bg-[#F6E8E9] w-full h-auto items-center pb-30 lg:pt-36 pt-10'>
{
aboutus.map((item, index) => {
const isEven = index % 2 === 0;
return (
<div>
<div className="hidden lg:flex relative w-[80vw] lg:mb-28 mb-10">
{isEven ? (
<div className='lg:grid lg:grid-cols-2 w-[80vw] mb-28'>
<div className="flex col-span-1 h-auto w-full ">
<img
src={`http://localhost/${item.image}`}
alt="Course Image"
className="w-full h-[25vw] object-cover object-center rounded-lg shadow-md"
style={{ aspectRatio: '1 / 1' }}
/>
</div>
<div className="relative flex col-span-1 w-full h-auto ml-16 items-center">
<div className="relative flex flex-col items-start w-[30vw]">
<p className="text-4xl">
{item.title}
</p>
{/* <p className="text-base overflow-hidden mt-8">
{item.description}
</p> */}
<div
className='mt-8 [&_*]:!text-[1.0rem] [&_*]:!text-gray-600 [&_*]'
dangerouslySetInnerHTML={{ __html: item.description }}
/>
</div>
</div>
</div>
) : (
<div className='lg:grid lg:grid-cols-2 w-[80vw] mb-28'>
<div className="relative flex col-span-1 w-full h-auto ml-16 items-center">
<div className="relative flex flex-col items-start w-[30vw]">
<p className="text-4xl">
{item.title}
</p>
{/* <p className="text-base overflow-hidden mt-8">
{item.description}
</p> */}
<div
className='mt-8 [&_*]:!text-[1.0rem] [&_*]:!text-gray-600 [&_*]:!text-start'
dangerouslySetInnerHTML={{ __html: item.description }}
/>
</div>
</div>
<div className="flex col-span-1 h-auto w-full justify-end ">
<img
src={`http://localhost/${item.image}`}
alt="Course Image"
className="w-full h-[25vw] object-cover object-center rounded-lg shadow-md"
style={{ aspectRatio: '1 / 1' }}
/>
</div>
</div>
)}
</div>
<div className="flex flex-col relative w-[80vw] lg:mb-28 mb-10 lg:hidden">
<div className="flex col-span-1 h-auto w-full ">
<img
src={`http://localhost/${item.image}`}
alt="Course Image"
className="w-full h-[44vw] object-cover object-center rounded-lg shadow-md"
style={{ aspectRatio: '1 / 1' }}
/>
</div>
<div className="relative flex flex-col lg:mt-0 mt-8">
<p className="lg:text-4xl text-3xl">
{item.title}
</p>
{/* <p className="text-base overflow-hidden mt-8">
{item.description}
</p> */}
<div
className='mt-8 [&_*]:!text-[1.0rem] [&_*]:!text-gray-600 [&_*]'
dangerouslySetInnerHTML={{ __html: item.description }}
/>
</div>
</div>
</div>
)
})
}
</div >
)
}
export default AboutusContent

View File

@ -0,0 +1,28 @@
import React from 'react'
import { CoursesProps } from '@/types'
const Banner = () => {
return (
<div className='relative flex w-full h-[30vh] lg:h-[50vh] bg-[#E5C6C8] items-center'>
<div className='flex-col flex lg:ml-48 ml-4 z-10'>
<p className='text-black lg:text-5xl text-3xl font-bold text-center'>
{"關於我們"}
</p>
<img src={"/images/line.png"} className='lg:w-[35vh] h-auto object-cover mt-2' />
</div>
{/* <div className='absolute bottom-0 right-0 max-sm:-right-32 md:-right-32 lg:right-32 bg-[url("/images/kid2.png")] bg-cover bg-center bg-no-repeat h-full w-[80%]'></div> */}
<div className=" w-full h-full">
<img
src={"/images/piano1.jpg"}
alt="piano1"
className="absolute right-0 object-cover object-left w-full h-full"
/>
<div className="absolute inset-0 bg-gradient-to-l from-transparent to-[#D4A3B0] opacity-100"></div>
</div>
</div>
)
}
export default Banner

View File

@ -0,0 +1,47 @@
"use client";
import { useState, useEffect, lazy, Suspense } from "react";
import Loading from '../Loading'
import Footer from '../Footer'
import ContactForm from "../ContactForm";
import AboutusContent from "./AboutusContent";
import Banner from "./Banner";
import Map from "./Map";
import { CoursesArrayProps, CoursesProps, SettingsProps, AboutusProps } from "@/types";
import Whatsapp from "../Whatsapp";
const Home = ({ courses, settings, aboutus }: { courses: CoursesProps[], settings: SettingsProps, aboutus: AboutusProps[] }) => {
const [loading, setLoading] = useState(true);
// const [courses, setCourses] = useState<CoursesProps[]>([]);
useEffect(() => {
const loadCourses = async () => {
setLoading(true);
await new Promise(resolve => setTimeout(resolve, 300)); // 0.5 second delay
setLoading(false);
}; loadCourses();
}, []);
const startLoading = () => setLoading(true);
const stopLoading = () => setLoading(false);
return (
<div className='bg-[#F2D5D5]'>
{loading ? (
<div className="flex justify-center items-center h-screen">
<Suspense fallback={<div>Loading...</div>}>
<Loading />
</Suspense>
</div>
) : (
<div>
<Banner />
<AboutusContent aboutus={aboutus} />
<Map settings={settings} />
<ContactForm startLoading={startLoading} stopLoading={stopLoading} />
<Footer settings={settings} />
</div>
)}
</div>
)
}
export default Home

View File

@ -0,0 +1,96 @@
"use client"
import React,{useEffect} from 'react'
import { GoogleMap, LoadScript, Marker } from '@react-google-maps/api';
import Loading from '../Loading'
import Link from 'next/link'
import { SettingsProps } from '@/types';
import { HiLocationMarker } from "react-icons/hi";
import { MdEmail } from "react-icons/md";
import { FaPhone } from "react-icons/fa6";
import mailgo from "mailgo";
const containerStyle = {
width: '100%',
height: '100%'
};
const Map = ({ settings }: { settings: SettingsProps }) => {
const center = {
lat: settings.latitude,
lng: settings.longitude,
};
useEffect(() => {
mailgo();
}, []);
return (
<div className='relative flex flex-col w-full h-auto items-center pb-30 bg-[#F6E8E9]'>
<div className='flex-col flex w-[80vw] h-[40vw] items-center rounded-lg overflow-hidden'>
<LoadScript googleMapsApiKey="AIzaSyBp6yD01sMuqJh2_OqmTjIUQa24Ykhn3Bo" loadingElement={<Loading />}>
<GoogleMap
mapContainerStyle={containerStyle}
zoom={18}
center={center}
>
<Marker key={"1"} position={center}
// icon={{ url: '/images/smalllogo.png', scaledSize: new window.google.maps.Size(40, 40) }}
/>
</GoogleMap>
</LoadScript>
</div>
<div className="flex justify-start w-[80vw] mt-10 mb-32">
<div className="flex flex-col lg:flex-row justify-between w-[70vw] ">
<div className='flex flex-row'>
<div className='flex h-6 w-6 justify-center items-center rounded-full bg-mainColor'>
<HiLocationMarker className='text-white' size={12} />
</div>
<div className='flex flex-col ml-3'>
<p>
{"地址"}
</p>
<button className='text-gray-700 hover:text-mainColor'
onClick={() => { window.open(`https://maps.google.com/?q=${settings.latitude},${settings.longitude}`, '_blank') }}>
{settings.address}
</button>
</div>
</div>
<div className='flex flex-row'>
<div className='flex h-6 w-6 items-center justify-center rounded-full bg-mainColor'>
<MdEmail className='text-white' size={12} />
</div>
<div className='flex flex-col ml-3'>
<p>
{"電郵"}
</p>
<Link href={`mailto:${settings.email}`}>
<p className='text-gray-700 hover:text-mainColor'>
{settings.email}
</p>
</Link>
</div>
</div>
<div className='flex flex-row'>
<div className='flex h-6 w-6 items-center justify-center rounded-full bg-mainColor'>
<FaPhone className='text-white' size={12} />
</div>
<div className='flex flex-col ml-3'>
<p>
{"電話"}
</p>
<Link href={`tel:${settings.phone}`}>
<p className='text-gray-700 hover:text-mainColor'>
{settings.phone}
</p>
</Link>
</div>
</div>
</div>
</div>
</div>
)
}
export default Map

View File

@ -34,72 +34,6 @@ async function reorganizedSchedule(schedule: ScheduleProps[]) {
const Accordion = async ({ courseData }: { courseData: CoursesProps }) => {
const newSchedule = await reorganizedSchedule(courseData.schedule)
const fakeData = [
{
"yearAndMonth": "2024年10月",
"schedule": [
{
"info2": "A room, 14F, Sha Tin Market, N.T.",
"info1": "11:00-12:00, 13:00-14:00, 15:00-16:00, 17:00-18:00",
"id": "e19a7934-82fe-4027-aca6-57a419e9623e",
"title": "A班",
"date": "2024-10-05T01:30:00Z",
"course_id": "29ab193d-2927-459d-9277-5520771b2dd6"
},
{
"info2": "Room B, Sheung Shui Village, N.T.",
"info1": "11:00-12:00, 13:00-14:00, 15:00-16:00, 17:00-18:00",
"id": "dc49a1b6-1c1f-44d6-bc52-b757aeba7b5b",
"title": "B班",
"date": "2024-10-05T01:31:00Z",
"course_id": "29ab193d-2927-459d-9277-5520771b2dd6"
},
{
"info2": "Room B, Sheung Shui Village, N.T.",
"info1": "11:00-12:00, 13:00-14:00, 15:00-16:00, 17:00-18:00",
"id": "d4785a90-311b-4a91-8fb7-beb077245f4f",
"title": "A班",
"date": "2024-10-06T01:31:00Z",
"course_id": "29ab193d-2927-459d-9277-5520771b2dd6"
}
]
},
{
"yearAndMonth": "2024年11月",
"schedule": [
{
"info2": "Room B, Sheung Shui Village, N.T.",
"info1": "11:00-12:00, 13:00-14:00, 15:00-16:00, 17:00-18:00",
"id": "5c88b2a7-6b4d-455f-b341-1fec3173d208",
"title": "A班",
"date": "2024-11-06T01:31:00Z",
"course_id": "29ab193d-2927-459d-9277-5520771b2dd6"
}
]
},
{
"yearAndMonth": "2025年01月",
"schedule": [
{
"info2": "Room B, Sheung Shui Village, N.T.",
"info1": "11:00-12:00, 13:00-14:00, 15:00-16:00, 17:00-18:00",
"id": "8a30dec2-63ed-4237-8f5b-177c42f29dda",
"title": "B班",
"date": "2025-01-04T01:31:00Z",
"course_id": "29ab193d-2927-459d-9277-5520771b2dd6"
},
{
"info2": "Room B, Sheung Shui Village, N.T.",
"info1": "11:00-12:00, 13:00-14:00, 15:00-16:00, 17:00-18:00",
"id": "86ddf906-499b-4dbd-967d-cc4dddd9f27b",
"title": "A班",
"date": "2025-01-05T01:31:00Z",
"course_id": "29ab193d-2927-459d-9277-5520771b2dd6"
}
]
}
]
console.log(newSchedule)
return (
<div className='relative flex flex-col w-full h-auto items-center pb-60'>
<Collapse title='課程資訊' children={courseData.information} />
@ -109,7 +43,7 @@ const Accordion = async ({ courseData }: { courseData: CoursesProps }) => {
{"課程時間表"}
</p>
{
fakeData.map((item, index) => {
newSchedule.map((item, index) => {
return (
<ScheduleCollapse key={index} title={item.yearAndMonth} rerganizedSchedule={{ yearAndMonth: item.yearAndMonth, schedules: item.schedule }} />
)

View File

@ -1,18 +1,47 @@
import React from 'react'
"use client"
import React, { useEffect, useState, lazy, Suspense } from 'react'
import Banner from './Banner'
import LongDesc from './LongDesc'
import CourseImagesSilder from './CourseImagesSilder'
import Accordion from './Accordion'
import { CoursesProps } from '@/types'
import { CoursesProps, SettingsProps } from '@/types'
import Footer from '../Footer'
const Course = ({ course }: { course: CoursesProps }) => {
import Loading from '../Loading'
const Course = ({ course, settings }: { course: CoursesProps, settings: SettingsProps }) => {
const [loading, setLoading] = useState(true);
// const [courses, setCourses] = useState<CoursesProps[]>([]);
useEffect(() => {
const loadCourses = async () => {
setLoading(true);
await new Promise(resolve => setTimeout(resolve, 300)); // 0.5 second delay
setLoading(false);
}; loadCourses();
}, []);
const startLoading = () => setLoading(true);
const stopLoading = () => setLoading(false);
return (
<div className='bg-[#F6E8E8]'>
<Banner courseData={course} />
<LongDesc courseData={course} />
<CourseImagesSilder courseData={course} />
<Accordion courseData={course} />
<Footer />
{loading ? (
<div className="flex justify-center items-center h-screen">
<Suspense fallback={<div>Loading...</div>}>
<Loading />
</Suspense>
</div>
) : (
<div>
<Banner courseData={course} />
<LongDesc courseData={course} />
<CourseImagesSilder courseData={course} />
<Accordion courseData={course} />
<Footer settings={settings} />
</div>
)}
</div>
)
}

View File

@ -67,7 +67,7 @@ const MobileNav = ({ closeNav, showNav, courses }: Props) => {
</div>
<div className='w-full h-16 flex justify-start items-center border-b-[1.5px] border-[#F5DADF]'>
<Link key={"03"} href={"#"} >
<Link key={"03"} href="/aboutus" >
<p className="text-xl ml-6 text-black">
</p>

View File

@ -81,7 +81,7 @@ const Nav = ({ openNav, courses, showNav, settings }: Props) => {
</div>
)}
</div>
<Link key={"03"} href={"#"} >
<Link key={"03"} href="/aboutus" >
<p className="nav__link">
{"關於我們"}
</p>
@ -93,7 +93,7 @@ const Nav = ({ openNav, courses, showNav, settings }: Props) => {
<div className="flex items-center space-x-5 ">
<div className="flex items-center space-x-2 max-sm:hidden">
<div className="bg-[#DCCECF] rounded-full h-8 w-8 flex items-center justify-center hover:bg-mainColor"
onClick={() => window.open(settings.facebook)} >
onClick={() => window.open(settings.facebook)} >
<FaFacebookF
className="w-4 h-4 cursor-pointer text-[#F6E5E9]"
/>

93
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "webfrontend",
"version": "0.1.0",
"dependencies": {
"@react-google-maps/api": "^2.19.3",
"animate.css": "^4.1.1",
"clsx": "^2.1.1",
"dotenv": "^16.4.5",
@ -15,6 +16,7 @@
"framer-motion": "^11.7.0",
"gsap": "^3.12.5",
"keen-slider": "^6.8.6",
"mailgo": "^0.12.2",
"moment": "^2.30.1",
"next": "14.2.13",
"nextjs-cors": "^2.2.0",
@ -137,6 +139,25 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@googlemaps/js-api-loader": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz",
"integrity": "sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA==",
"license": "Apache-2.0",
"dependencies": {
"fast-deep-equal": "^3.1.3"
}
},
"node_modules/@googlemaps/markerclusterer": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.5.3.tgz",
"integrity": "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==",
"license": "Apache-2.0",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"supercluster": "^8.0.1"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
@ -494,6 +515,36 @@
"node": ">=14"
}
},
"node_modules/@react-google-maps/api": {
"version": "2.19.3",
"resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.19.3.tgz",
"integrity": "sha512-jiLqvuOt5lOowkLeq7d077AByTyJp+s6hZVlLhlq7SBacBD37aUNpXBz2OsazfeR6Aw4a+9RRhAEjEFvrR1f5A==",
"license": "MIT",
"dependencies": {
"@googlemaps/js-api-loader": "1.16.2",
"@googlemaps/markerclusterer": "2.5.3",
"@react-google-maps/infobox": "2.19.2",
"@react-google-maps/marker-clusterer": "2.19.2",
"@types/google.maps": "3.55.2",
"invariant": "2.2.4"
},
"peerDependencies": {
"react": "^16.8 || ^17 || ^18",
"react-dom": "^16.8 || ^17 || ^18"
}
},
"node_modules/@react-google-maps/infobox": {
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.19.2.tgz",
"integrity": "sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg==",
"license": "MIT"
},
"node_modules/@react-google-maps/marker-clusterer": {
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz",
"integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw==",
"license": "MIT"
},
"node_modules/@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
@ -524,6 +575,12 @@
"tslib": "^2.4.0"
}
},
"node_modules/@types/google.maps": {
"version": "3.55.2",
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.2.tgz",
"integrity": "sha512-JcTwzkxskR8DN/nnX96Pie3gGN3WHiPpuxzuQ9z3516o1bB243d8w8DHUJ8BohuzoT1o3HUFta2ns/mkZC8KRw==",
"license": "MIT"
},
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -2348,7 +2405,6 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-glob": {
@ -2929,6 +2985,15 @@
"node": ">= 0.4"
}
},
"node_modules/invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@ -3496,6 +3561,12 @@
"node": ">=4.0"
}
},
"node_modules/kdbush": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
"integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==",
"license": "ISC"
},
"node_modules/keen-slider": {
"version": "6.8.6",
"resolved": "https://registry.npmjs.org/keen-slider/-/keen-slider-6.8.6.tgz",
@ -3617,6 +3688,17 @@
"dev": true,
"license": "ISC"
},
"node_modules/mailgo": {
"version": "0.12.2",
"resolved": "https://registry.npmjs.org/mailgo/-/mailgo-0.12.2.tgz",
"integrity": "sha512-iX4F3eOhPJ+12YlM51UNV8yTYwxHywaGP1C9Qaep/iNP2ZS+xzqHR7U3o+7HoCL19gZKysc7+MwgBEiRy8ogzA==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mailgo"
}
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@ -5214,6 +5296,15 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/supercluster": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz",
"integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==",
"license": "ISC",
"dependencies": {
"kdbush": "^4.0.2"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",

View File

@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@react-google-maps/api": "^2.19.3",
"animate.css": "^4.1.1",
"clsx": "^2.1.1",
"dotenv": "^16.4.5",
@ -16,6 +17,7 @@
"framer-motion": "^11.7.0",
"gsap": "^3.12.5",
"keen-slider": "^6.8.6",
"mailgo": "^0.12.2",
"moment": "^2.30.1",
"next": "14.2.13",
"nextjs-cors": "^2.2.0",

BIN
public/images/piano1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
public/images/smalllogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -17,6 +17,14 @@ export interface SettingsProps {
}
export interface AboutusProps {
id: string;
title: string;
description: string
image: string;
index: number;
}
export interface MessageProps {
name: string,
phone: string,

View File

@ -1,5 +1,5 @@
import { CoursesProps, CoursesArrayProps, SettingsProps, MessageProps } from "@/types";
import { CoursesProps, CoursesArrayProps, SettingsProps, MessageProps, AboutusProps } from "@/types";
@ -37,6 +37,30 @@ export async function postMessage(data: MessageProps) {
}
}
export async function fetchAboutus() {
const headers: HeadersInit = {
accept: "application/json"
};
const url = `${process.env.api_url}aboutUs`;
console.log('Fetching from URL:', url);
try {
const response = await fetch(url, { headers });
console.log('Response status:', response.status);
const result = await response.json();
console.log('Fetched data:', result);
// Sort the result by index
const sortedResult: AboutusProps[] = result.data.sort((a: any, b: any) => a.index - b.index);
return sortedResult;
}
catch (error) {
console.error('Fetch error:', error);
throw error;
}
}
export async function fetchCourses() {
const headers: HeadersInit = {