diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..9bac650 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +allowBuilds: + '@swc/core': false + esbuild: false diff --git a/src/components/UI/Divider/SGLDivider.tsx b/src/components/UI/Divider/SGLDivider.tsx new file mode 100644 index 0000000..a711427 --- /dev/null +++ b/src/components/UI/Divider/SGLDivider.tsx @@ -0,0 +1,16 @@ +import { Box, useTheme } from '@mui/material' +import { getDividerStyles } from './styles' + +interface SGLDividerProps { + orientation?: 'horizontal' | 'vertical' +} + +export const SGLDivider = ({ orientation = 'horizontal' }: SGLDividerProps = {}) => { + const theme = useTheme() + const dividerStyles = getDividerStyles(theme) + + const styles = + orientation === 'vertical' ? dividerStyles.dividerVertical : dividerStyles.dividerHorizontal + + return +} diff --git a/src/components/UI/Divider/index.ts b/src/components/UI/Divider/index.ts new file mode 100644 index 0000000..0d7218e --- /dev/null +++ b/src/components/UI/Divider/index.ts @@ -0,0 +1 @@ +export { SGLDivider } from './SGLDivider' diff --git a/src/components/UI/Divider/styles.ts b/src/components/UI/Divider/styles.ts index 83ad16f..eb71243 100644 --- a/src/components/UI/Divider/styles.ts +++ b/src/components/UI/Divider/styles.ts @@ -1,5 +1,25 @@ -import { styled } from '@mui/material' +import type { Theme } from '@mui/material' +import type { CSSProperties } from 'react' -export const SGLDivider = styled('div')(() => ({ - display: 'none', -})) +export interface DividerStylesInterface { + dividerHorizontal: CSSProperties + dividerVertical: CSSProperties +} + +export const getDividerStyles = (theme: Theme): DividerStylesInterface => ({ + dividerHorizontal: { + width: '100%', + height: '1px', + backgroundColor: theme.palette.mediumGrey?.main || '#e0e0e0', + marginTop: '1.5rem', + marginBottom: '1.5rem', + }, + + dividerVertical: { + width: '1px', + height: '100%', + backgroundColor: theme.palette.mediumGrey?.main || '#e0e0e0', + marginLeft: '1.5rem', + marginRight: '1.5rem', + }, +}) diff --git a/src/locales/ar/translation.json b/src/locales/ar/translation.json index 4272cf5..e1e5f8c 100644 --- a/src/locales/ar/translation.json +++ b/src/locales/ar/translation.json @@ -84,5 +84,11 @@ "lifeStyle.morningStretchingTitle": "تمارين التمدد الصباحية", "lifeStyle.morningStretchingDescription": "تحسين تدفق الدم والمرونة", "lifeStyle.balanceTrainingTitle": "تمارين التوازن", - "lifeStyle.balanceTrainingDescription": "تقوية عضلات الجسم الأساسية وتحسين القوام" + "lifeStyle.balanceTrainingDescription": "تقوية عضلات الجسم الأساسية وتحسين القوام", + "mealRecommendation.viewFullRecipe": "عرض الوصفة الكاملة", + "mealRecommendation.close": "إغلاق", + "mealRecommendation.lunch": "غداء موصى به", + "mealRecommendation.breakfast": "إفطار موصى به", + "mealRecommendation.dinner": "عشاء موصى به", + "mealRecommendation.dailyMeals": "وجباتك اليومية" } diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 403a887..712f4db 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -131,5 +131,11 @@ "lifeStyle.morningStretchingTitle": "Morning Stretching", "lifeStyle.morningStretchingDescription": "Improve Blood Flow and Flexibility", "lifeStyle.balanceTrainingTitle": "Balance Training", - "lifeStyle.balanceTrainingDescription": "Strengthen Core Muscles and Posture" + "lifeStyle.balanceTrainingDescription": "Strengthen Core Muscles and Posture", + "mealRecommendation.viewFullRecipe": "View Full Recipe", + "mealRecommendation.close": "Close", + "mealRecommendation.lunch": "Recommended Lunch", + "mealRecommendation.breakfast": "Recommended Breakfast", + "mealRecommendation.dinner": "Recommended Dinner", + "mealRecommendation.dailyMeals": "Your Daily Meals" } diff --git a/src/locales/he/translation.json b/src/locales/he/translation.json index db0aa5b..186801c 100644 --- a/src/locales/he/translation.json +++ b/src/locales/he/translation.json @@ -132,5 +132,11 @@ "lifeStyle.morningStretchingTitle": "מתיחות בוקר", "lifeStyle.morningStretchingDescription": "שיפור זרימת דם וגמישות", "lifeStyle.balanceTrainingTitle": "אימון שיווי משקל", - "lifeStyle.balanceTrainingDescription": "חיזוק שרירי ליבה ויציבה" + "lifeStyle.balanceTrainingDescription": "חיזוק שרירי ליבה ויציבה", + "mealRecommendation.viewFullRecipe": "צפה במתכון המלא", + "mealRecommendation.close": "סגור", + "mealRecommendation.lunch": "ארוחת צהריים מומלצת", + "mealRecommendation.breakfast": "ארוחת בוקר מומלצת", + "mealRecommendation.dinner": "ארוחת ערב מומלצת", + "mealRecommendation.dailyMeals": "הארוחות המומלצות שלך" } diff --git a/src/locales/ru/translation.json b/src/locales/ru/translation.json index 825f4fb..ac16e62 100644 --- a/src/locales/ru/translation.json +++ b/src/locales/ru/translation.json @@ -131,5 +131,11 @@ "lifeStyle.morningStretchingTitle": "Утренняя растяжка", "lifeStyle.morningStretchingDescription": "Улучшение кровообращения и гибкости", "lifeStyle.balanceTrainingTitle": "Тренировка равновесия", - "lifeStyle.balanceTrainingDescription": "Укрепление мышц кора и осанки" + "lifeStyle.balanceTrainingDescription": "Укрепление мышц кора и осанки", + "mealRecommendation.viewFullRecipe": "Просмотреть полный рецепт", + "mealRecommendation.close": "Закрыть", + "mealRecommendation.lunch": "Рекомендуемый обед", + "mealRecommendation.breakfast": "Рекомендуемый завтрак", + "mealRecommendation.dinner": "Рекомендуемый ужин", + "mealRecommendation.dailyMeals": "Ваши ежедневные приемы пищи" } diff --git a/src/pages/lifeStyle/LifeStyle.tsx b/src/pages/lifeStyle/LifeStyle.tsx index 743df60..2e4fe58 100644 --- a/src/pages/lifeStyle/LifeStyle.tsx +++ b/src/pages/lifeStyle/LifeStyle.tsx @@ -1,5 +1,16 @@ +import { useTranslation } from 'react-i18next' +import { BalanceTraining } from './physioAndTrainingTab/balanceTraining/BalanceTraining' +import { DietTabExample } from './dietTab/DietTabExample' import { RecomendationTraining } from './physioAndTrainingTab/recomendationTraining/RecomendationTraining' export const LifeStyle = () => { - return + const { t } = useTranslation() + return ( + <> +
{t('lifestyle.page')}
+ + + + + ) } diff --git a/src/pages/lifeStyle/dietTab/DietTabExample.tsx b/src/pages/lifeStyle/dietTab/DietTabExample.tsx new file mode 100644 index 0000000..fce59d4 --- /dev/null +++ b/src/pages/lifeStyle/dietTab/DietTabExample.tsx @@ -0,0 +1,87 @@ +import { useTranslation } from 'react-i18next' +import { SGLMealRecommendation } from './mealRecommendation' + +export const DietTabExample = () => { + const { t } = useTranslation() + const mealsData = [ + { + mealType: 'ארוחת צהריים מומלצת', + name: 'סלמון אפוי', + recipe: 'סלמון טרי אפוי עם לימון וצמחי תיבול', + fullRecipe: `סלמון אפוי עם לימון וצמחי תיבול - מומלץ מאוד לבריאות הלב + +חומרים: +• 200 גר סלמון טרי +• לימון אחד +• בזיליקום, כוסברה, דיל +• שמן זית + +הוראות: +1. חמם תנור ל-180 מעלות +2. הנח סלמון על נייר אפייה +3. ריסה עם שמן זית, מלח ופלפל +4. פזר צמחי תיבול +5. אפה 15-20 דקות עד שהסלמון בשל +6. הגש עם לימון טרי`, + }, + { + mealType: 'חטיף מומלץ', + name: 'סלט ירוקים', + recipe: 'תערובת ירוקים טרייה עם עגבניה ומלפפון', + fullRecipe: `סלט ירוקים טרי ובריא + +חומרים: +• עלי סלט מעורבים 150 גר +• 2 עגבניות בינוניות +• מלפפון אחד +• בצל אדום קצוץ +• זיתים שחורים +• שמן זית וחומץ בלסמי + +הוראות: +1. שטוף את הירוקים היטב +2. חתוך את הירקות לגדלים נוחים +3. מיזג את כל החומרים בקערה +4. מחבל שמן זית וחומץ בחומס בנפרד +5. מוזג את הרוטב על הסלט +6. ערבב ברכות`, + }, + { + mealType: 'ארוחת ערב מומלצת', + name: 'עוף ברוטב עלים', + recipe: 'עוף צלול עם רוטב עלים טבעי וחומרים מזינים', + fullRecipe: `עוף ברוטב עלים טבעי + +חומרים: +• 250 גר בקע עוף +• 100 מ"ל מרק עוף +• כוסברית, בזיליקום, כוסבר +• שום 2 שיניים +• שמן זית + +הוראות: +1. חמם שמן זית בחליה +2. הוסף בקע עוף עד להשחמה +3. הוסף שום קצוץ +4. שפוך מרק עוף +5. הוסף צמחי תיבול +6. בישול על אש בינונית 15-20 דקות +7. הגש חם`, + }, + ] + + return ( +
+

{t('mealRecommendation.dailyMeals')}

+ {mealsData.map((meal, index) => ( + + ))} +
+ ) +} diff --git a/src/pages/lifeStyle/dietTab/mealRecommendation/MealCard.tsx b/src/pages/lifeStyle/dietTab/mealRecommendation/MealCard.tsx new file mode 100644 index 0000000..b506e28 --- /dev/null +++ b/src/pages/lifeStyle/dietTab/mealRecommendation/MealCard.tsx @@ -0,0 +1,51 @@ +import { Typography } from '@mui/material' +import { useTheme } from '@mui/material' +import { useTranslation } from 'react-i18next' +import { getMealRecommendationStyles } from './styles' +import { SGLButton } from '../../../../components/UI/Button/SGLButton' +import { SGLCard } from '../../../../components/UI/Card/SGLCard' +import { SGLLink } from '../../../../components/UI/Icons/Link/SGLLink' +import { SGLTypography } from '../../../../components/UI/Typography/SGLTypography' +import { variantMap } from '../../../../components/UI/Typography/types' + +interface MealCardProps { + mealType: string + name: string + recipe: string + imageUrl?: string + onOpenDialog: () => void +} + +export const MealCard = ({ mealType, name, recipe, imageUrl, onOpenDialog }: MealCardProps) => { + const theme = useTheme() + const { t } = useTranslation() + const styles = getMealRecommendationStyles(theme) + + return ( + <> + + {mealType} + + +
+
+
+ +
+
+
+ {name} + {recipe} +
+
+ + + {t('mealRecommendation.viewFullRecipe')} + + +
+
+
+ + ) +} diff --git a/src/pages/lifeStyle/dietTab/mealRecommendation/MealDialog.tsx b/src/pages/lifeStyle/dietTab/mealRecommendation/MealDialog.tsx new file mode 100644 index 0000000..b9a668f --- /dev/null +++ b/src/pages/lifeStyle/dietTab/mealRecommendation/MealDialog.tsx @@ -0,0 +1,34 @@ +import { Typography, Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material' +import { useTheme } from '@mui/material' +import { useTranslation } from 'react-i18next' +import { getMealRecommendationStyles } from './styles' +import { SGLButton } from '../../../../components/UI/Button/SGLButton' +import { variantMap } from '../../../../components/UI/Typography/types' + +interface MealDialogProps { + name: string + recipe: string + fullRecipe?: string + open: boolean + onClose: () => void +} + +export const MealDialog = ({ name, recipe, fullRecipe, open, onClose }: MealDialogProps) => { + const theme = useTheme() + const { t } = useTranslation() + const styles = getMealRecommendationStyles(theme) + + return ( + + {name} + + {fullRecipe || recipe} + + + + {t('mealRecommendation.close')} + + + + ) +} diff --git a/src/pages/lifeStyle/dietTab/mealRecommendation/MealRecommendation.tsx b/src/pages/lifeStyle/dietTab/mealRecommendation/MealRecommendation.tsx new file mode 100644 index 0000000..5b18fc7 --- /dev/null +++ b/src/pages/lifeStyle/dietTab/mealRecommendation/MealRecommendation.tsx @@ -0,0 +1,40 @@ +import { useState } from 'react' +import { MealCard } from './MealCard' +import { MealDialog } from './MealDialog' + +interface SGLMealRecommendationProps { + mealType: string + name: string + recipe: string + fullRecipe?: string + imageUrl?: string +} + +export const SGLMealRecommendation = ({ + mealType, + name, + recipe, + fullRecipe, + imageUrl, +}: SGLMealRecommendationProps) => { + const [openDialog, setOpenDialog] = useState(false) + + return ( + <> + setOpenDialog(true)} + /> + setOpenDialog(false)} + /> + + ) +} diff --git a/src/pages/lifeStyle/dietTab/mealRecommendation/index.ts b/src/pages/lifeStyle/dietTab/mealRecommendation/index.ts new file mode 100644 index 0000000..cd9c351 --- /dev/null +++ b/src/pages/lifeStyle/dietTab/mealRecommendation/index.ts @@ -0,0 +1 @@ +export { SGLMealRecommendation } from './MealRecommendation' diff --git a/src/pages/lifeStyle/dietTab/mealRecommendation/styles.ts b/src/pages/lifeStyle/dietTab/mealRecommendation/styles.ts new file mode 100644 index 0000000..c124402 --- /dev/null +++ b/src/pages/lifeStyle/dietTab/mealRecommendation/styles.ts @@ -0,0 +1,92 @@ +import type { Theme, SxProps } from '@mui/material' +import type { CSSProperties } from '@mui/material' + +export interface MealRecommendationStylesInterface { + container: CSSProperties + heroImage: (imageUrl?: string) => CSSProperties + iconContainer: CSSProperties + content: CSSProperties + buttonWrapper: CSSProperties + mealButton: (theme: Theme) => SxProps + closeButton: SxProps + dialogTitle: SxProps + linkIcon: { + size: number + color: string + strokeWidth: number + } +} + +export const getMealRecommendationStyles = (theme: Theme): MealRecommendationStylesInterface => ({ + container: { + display: 'flex', + flexDirection: 'column', + overflow: 'hidden', + marginBottom: theme.spacing(2), + } as CSSProperties, + + heroImage: (imageUrl?: string) => + ({ + width: '100%', + height: '180px', + backgroundColor: theme.palette.lightGrey.main, + backgroundImage: imageUrl ? `url(${imageUrl})` : 'none', + backgroundSize: 'cover', + backgroundPosition: 'center', + display: 'flex', + alignItems: 'flex-start', + justifyContent: 'flex-end', + padding: theme.spacing(1.5), + }) as CSSProperties, + + iconContainer: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + width: '40px', + height: '40px', + borderRadius: '50%', + backgroundColor: theme.palette.lowOpacityWhite.main, + } as CSSProperties, + + content: { + padding: theme.spacing(2), + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1), + textAlign: 'center', + } as CSSProperties, + + buttonWrapper: { + padding: theme.spacing(1.5), + } as CSSProperties, + + mealButton: (theme: Theme) => + ({ + gap: '0.5rem', + backgroundColor: theme.palette.background.paper, + color: theme.palette.purple.main, + border: `1px solid ${theme.palette.mediumGrey.main}`, + width: '100%', + transition: 'background-color 0.2s ease', + '&:hover': { + backgroundColor: theme.palette.purple50.main, + }, + }) as SxProps, + + closeButton: { + backgroundColor: theme.palette.purple.main, + color: theme.palette.background.paper, + } as SxProps, + + dialogTitle: { + textAlign: 'center', + fontWeight: 700, + } as SxProps, + + linkIcon: { + size: 20, + color: theme.palette.midGrey.main, + strokeWidth: 2.5, + }, +}) diff --git a/src/theme.d.ts b/src/theme.d.ts index 4494131..9822b12 100644 --- a/src/theme.d.ts +++ b/src/theme.d.ts @@ -1,4 +1,15 @@ declare module '@mui/material/styles' { + interface BreakpointOverrides { + xs: false + sm: false + md: false + lg: false + xl: false + mobile: true + tablet: true + laptop: true + desktop: true + } interface Palette { purple: Palette['primary'] brown: Palette['primary'] @@ -14,17 +25,15 @@ declare module '@mui/material/styles' { midGrey: Palette['primary'] lowOpacityGrey: Palette['primary'] lowOpacityPurple: Palette['primary'] - lowOpacityGrey: Palette['primary'] lowOpacityYellow: Palette['primary'] lowOpacityWhite: Palette['primary'] blue: Palette['primary'] emerald: Palette['primary'] lightGreen: Palette['primary'] darkGreen: Palette['primary'] - yellow: Palette['primary'] - brown: Palette['primary'] lightOrange: Palette['primary'] warmBrown: Palette['primary'] + purple50: Palette['primary'] darkOrange: Palette['primary'] darkPurple: Palette['primary'] } @@ -43,17 +52,15 @@ declare module '@mui/material/styles' { midGrey?: PaletteOptions['primary'] lowOpacityGrey?: PaletteOptions['primary'] lowOpacityPurple?: PaletteOptions['primary'] - lowOpacityGrey?: PaletteOptions['primary'] lowOpacityYellow?: PaletteOptions['primary'] lowOpacityWhite?: PaletteOptions['primary'] blue?: PaletteOptions['primary'] emerald?: PaletteOptions['primary'] lightGreen?: PaletteOptions['primary'] darkGreen?: PaletteOptions['primary'] - yellow?: PaletteOptions['primary'] - brown?: PaletteOptions['primary'] lightOrange?: PaletteOptions['primary'] warmBrown?: PaletteOptions['primary'] + purple50?: PaletteOptions['primary'] darkOrange?: PaletteOptions['primary'] darkPurple?: PaletteOptions['primary'] } diff --git a/src/theme.ts b/src/theme.ts index b046430..9341152 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -111,6 +111,9 @@ export const theme = createTheme({ darkOrange: { main: '#ef4444', }, + purple50: { + main: '#FAF5FF', + }, darkPurple: { main: '#6b21a8', },