Files
healthy_oil/src/components/new_ui/info.tsx
2025-11-04 12:50:27 +08:00

166 lines
8.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;