166 lines
8.0 KiB
TypeScript
166 lines
8.0 KiB
TypeScript
import { Box, Stack, Image, Flex, Text } from '@chakra-ui/react'
|
||
import { useState } from 'react'
|
||
import { motion } from 'framer-motion'
|
||
|
||
const MotionImage = motion.create(Image)
|
||
const MotionFlex = motion.create(Flex)
|
||
const MotionBox = motion.create(Box)
|
||
|
||
interface InfoData {
|
||
id: number
|
||
title: string
|
||
image: string
|
||
description: string
|
||
}
|
||
|
||
const infoData: InfoData[] = [
|
||
{
|
||
id: 1,
|
||
title: '膽固醇\n超標',
|
||
image: '/images/new/info_1.webp',
|
||
description: `長期攝取過多**飽和脂肪及反式脂肪(例如牛油、加工食品、或重複使用嘅煎炸油)**,會令體內**壞膽固醇(LDL)上升、好膽固醇(HDL)下降**,導致膽固醇積聚喺血管內壁,形成血塊堵塞血管,有機會引致**中風、心肌梗塞,**甚至**心臟病**等嚴重後果。`
|
||
},
|
||
{
|
||
id: 2,
|
||
title: '中央肥胖\n脂肪肝',
|
||
image: '/images/new/info_2.webp',
|
||
description: `研究指出,將煎炸油長時間加熱至超過煙點或重複使用,會令**油質氧化,**產生聚合物及自由基。前者會令油變黏稠、有油膩味,**增加肝臟負擔;**後者會攻擊細胞,加速身體衰老並提升患上慢性病嘅風險。
|
||
|
||
長期攝取呢類油脂,會干擾身體脂肪代謝速度,**令過多脂肪積聚喺肝臟,**並削弱其解毒功能,令毒素累積喺體內,最終導致**脂肪肝**。如果肝臟持續受損,可能就會留下永久損傷,最後導致**肝硬化**。`
|
||
},
|
||
{
|
||
id: 3,
|
||
title: '皮膚暗啞\n容易脫髮',
|
||
image: '/images/new/info_3.webp',
|
||
description: `好多人以為「滴油不沾」先健康,但其實**持續攝取適量又優質嘅油脂,**先可以促進毛髮健康生長,同時令皮膚保持彈性同水潤。
|
||
|
||
因為**脂肪係製造荷爾蒙**嘅重要原素,而脂溶性維他命A、D、E、K亦必須喺有油嘅情況下先可以被吸收,長遠先能真正發揮對皮膚、頭髮同整體健康嘅作用,呈現由內而外嘅自然光澤。`
|
||
},
|
||
{
|
||
id: 4,
|
||
title: '經常容易\n覺得疲倦',
|
||
image: '/images/new/info_4.webp',
|
||
description: `香港人生活節奏急促,一日三餐唔係叫外賣就出街食,而餐廳普遍使用 Omega-6 偏高嘅食油(如大豆油)。**長期攝取會令體內Omega-6遠多於Omega-3,脂肪酸比例失衡,促進身體慢性發炎。**
|
||
|
||
如果失衡未能改善,尤其Omega-3長期攝取不足,就容易出現易攰、記憶力下降、專注力不足等情況。隨住狀況持續惡化,仲可能影響腦部神經傳導,提升**腦霧同失智症**風險。`
|
||
}
|
||
]
|
||
|
||
const renderDescription = (text: string) => {
|
||
const parts = text.split(/(\*\*.*?\*\*)/)
|
||
|
||
return parts.map((part, index) => {
|
||
if (part.startsWith('**') && part.endsWith('**')) {
|
||
return (
|
||
<Text as="span" key={index} fontWeight={800}>
|
||
{part.slice(2, -2)}
|
||
</Text>
|
||
)
|
||
}
|
||
return <Text as="span" key={index}>{part}</Text>
|
||
})
|
||
}
|
||
|
||
function Info() {
|
||
const [selectedInfo, setSelectedInfo] = useState<number>(1)
|
||
|
||
return (
|
||
<Box
|
||
id="info"
|
||
position="relative"
|
||
w="100%"
|
||
minH={{ base: "163vw", sm: "163vw", md: "75vw", lg: "50vw", xl: "45vw" }}
|
||
bgColor="#4E8C36"
|
||
zIndex={3}
|
||
overflow="hidden"
|
||
justifyItems={'center'}
|
||
>
|
||
<Stack alignItems={'center'} gap={{ base: 4, sm: 4, md: 6, lg: 8, xl: 8 }}>
|
||
<MotionImage
|
||
src='/images/new/info_title.webp'
|
||
w={{ base: '90vw', sm: '80vw', md: '45vw', lg: '35vw', xl: '22vw' }}
|
||
mt={'50px'}
|
||
initial={{ opacity: 0, y: -30 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true, amount: 0.3 }}
|
||
transition={{ duration: 0.8, ease: "easeOut" }}
|
||
/>
|
||
|
||
<MotionFlex
|
||
gap={{ base: 1, sm: 2, md: 3, lg: 4, xl: 2 }}
|
||
flexWrap="wrap"
|
||
justifyContent="center"
|
||
px={{ base: 4, sm: 4, md: 0, lg: 0, xl: 0 }}
|
||
initial={{ opacity: 0, y: 30 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true, amount: 0.3 }}
|
||
transition={{ duration: 0.8, delay: 0.2, ease: "easeOut" }}
|
||
>
|
||
{infoData.map((info) => (
|
||
<Box
|
||
key={info.id}
|
||
w={{ base: '20vw', sm: '110px', md: '150px', lg: '150px', xl: '150px' }}
|
||
h={{ base: '15vw', sm: '70px', md: '90px', lg: '90px', xl: '90px' }}
|
||
cursor="pointer"
|
||
onClick={() => setSelectedInfo(info.id)}
|
||
bg={selectedInfo === info.id ? '#3D6741' : '#BCBCBC'}
|
||
border={selectedInfo === info.id ? { base: "1px solid #99BF35", sm: "1px solid #99BF35", md: "4px solid #99BF35", lg: "4px solid #99BF35", xl: "4px solid #99BF35" } : "none"}
|
||
borderRadius={{ base: '15px', sm: '15px', md: '18px', lg: '20px', xl: '20px' }}
|
||
display="flex"
|
||
alignItems="center"
|
||
justifyContent="center"
|
||
textAlign="center"
|
||
fontFamily="'MElleHK', sans-serif"
|
||
fontWeight={selectedInfo === info.id ? 800 : 500}
|
||
fontSize={{ base: '3.5vw', sm: '19px', md: '2xl', lg: '2xl', xl: '2xl' }}
|
||
color={selectedInfo === info.id ? '#FFFFFF' : '#DDDDDD'}
|
||
whiteSpace="pre-line"
|
||
lineHeight="1.2"
|
||
transition="all 0.3s ease"
|
||
px={2}
|
||
boxShadow={info.id === selectedInfo ? "inset 3px 3px 3px rgba(0,0,0,0.25), 4px 4px 10px rgba(0,0,0,0.45)" : info.id === selectedInfo + 1 ? "inset 3px 3px 3px rgba(0,0,0,0.25)" : "none"}
|
||
>
|
||
{info.title}
|
||
</Box>
|
||
))}
|
||
</MotionFlex>
|
||
|
||
<MotionBox
|
||
w={{ base: '83vw', sm: '460px', md: '500px', lg: '500px', xl: '500px' }}
|
||
bg="white"
|
||
justifyItems={'center'}
|
||
overflow="hidden"
|
||
borderRadius="20px"
|
||
mb={{ base: 8, sm: 8, md: 12, lg: 16, xl: 16 }}
|
||
boxShadow="0 4px 20px rgba(0,0,0,0.15)"
|
||
initial={{ opacity: 0, scale: 0.9 }}
|
||
whileInView={{ opacity: 1, scale: 1 }}
|
||
viewport={{ once: true, amount: 0.3 }}
|
||
transition={{ duration: 0.8, delay: 0.4, ease: "easeOut" }}
|
||
>
|
||
<Image
|
||
src={infoData.find(info => info.id === selectedInfo)?.image}
|
||
w="100%"
|
||
p={5}
|
||
|
||
/>
|
||
<Box px={{ base: 5, sm: 5, md: 6, lg: 5, xl: 5 }}
|
||
pb={{ base: 5, sm: 5, md: 6, lg: 9, xl: 9 }}>
|
||
<Text
|
||
className="font-noto-sans font-regular"
|
||
fontSize={{ base: 'md', sm: 'lg', md: 'xl', lg: '2xl', xl: '2xl' }}
|
||
color="#3D6741"
|
||
lineHeight="1.8"
|
||
textAlign="left"
|
||
whiteSpace="pre-wrap"
|
||
>
|
||
{renderDescription(infoData.find(info => info.id === selectedInfo)?.description || '')}
|
||
</Text>
|
||
</Box>
|
||
</MotionBox>
|
||
</Stack>
|
||
</Box >
|
||
)
|
||
}
|
||
|
||
export default Info; |