Merge branch 'Common_Quizz' of https://codefirst.iut.uca.fr/git/Optifit/Mobile into Common_Quizz

pull/8/head
Vianney JOURDY 5 months ago
commit 775bb1cb2e

@ -1,7 +1,8 @@
import BackButton from "@/components/BackButton";
import GoalQuestion from "@/components/quiz/GoalQuestion";
import LvlQuestion from "@/components/quiz/LvlQuestion";
import { toBgColor, toTextColor } from "@/components/Constants";
import HeightQuestion from "@/components/quiz/HeightQuestion";
import { QuestionChildProps } from "@/components/quiz/Question";
import WeightQuestion from "@/components/quiz/WeightQuestion";
import Button from "@/components/ui/Button";
import Screen from "@/components/ui/Screen";
import Text from "@/components/ui/Text";
@ -12,7 +13,7 @@ export default function Quiz() {
const [currentQuestionIndex, setCurrentQuestionIndex] = React.useState(0);
const questions: ForwardRefExoticComponent<
QuestionChildProps & RefAttributes<any>
>[] = [GoalQuestion, LvlQuestion];
>[] = [WeightQuestion, HeightQuestion];
const goBack = () => {
if (currentQuestionIndex >= 1) {
@ -31,9 +32,9 @@ export default function Quiz() {
<View className="gap-4 justify-between h-full">
<View className="flex-row justify-between items-center">
<BackButton onPress={goBack} />
<View>
<Text>
Question {currentQuestionIndex + 1} / {questions.length}
<View className={"px-4 py-2 rounded-2xl" + " " + toBgColor("blue")}>
<Text className={toTextColor("blue")} weight="bold">
{currentQuestionIndex + 1} sur {questions.length}
</Text>
</View>
</View>

@ -1,30 +1,56 @@
import { Link, Stack, usePathname } from 'expo-router';
import {StyleSheet, Text, View} from 'react-native';
import React from "react";
import {
View,
Text,
Image,
TouchableOpacity,
SafeAreaView,
StatusBar,
} from "react-native";
export default function NotFoundScreen() {
const pathname = usePathname();
return (
<>
<Stack.Screen options={{ title: 'Oops!' }} />
<View style={styles.container}>
<Text>This screen {pathname} doesn't exist: {pathname}</Text>
<Text>Go to home screen!</Text>
<SafeAreaView className="flex-1 bg-white">
<StatusBar barStyle="dark-content" />
{/* Back Button Area */}
<View className="p-4 absolute top-11 left-0 z-10">
<Text className="text-2xl text-gray-300"></Text>
</View>
{/* Main Content */}
<View className="flex-1 items-center justify-center px-5">
{/* Magnifying Glass Image */}
<Image
source={{
uri: "https://hebbkx1anhila5yf.public.blob.vercel-storage.com/Capture%20d%E2%80%99e%CC%81cran%202025-01-21%20a%CC%80%2008.21.49-5FFPPKCnwJH2QV30OeJup36tsu0CGA.png",
}}
className="w-[200px] h-[200px] mb-10"
resizeMode="contain"
/>
{/* Error Text */}
<Text className="text-4xl font-bold text-gray-800 mb-4">Not Found</Text>
{/* Error Message */}
<Text className="text-lg text-gray-600 text-center mb-6">
Whoops! Coach S can't find this page :(
</Text>
{/* Status Code */}
<View className="bg-red-100/20 py-2 px-4 rounded-lg flex-row items-center mb-10">
<Text className="text-red-400 text-base">
:warning: Status Code: 404
</Text>
</View>
{/* Home Button */}
<TouchableOpacity className="bg-[#F4804F] py-4 px-8 rounded-full flex-row items-center absolute bottom-10 left-5 right-5">
<Text className="text-white text-lg font-semibold text-center flex-1">
Take Me Home
</Text>
</TouchableOpacity>
</View>
</>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
link: {
marginTop: 15,
paddingVertical: 15,
},
});

@ -5,6 +5,6 @@ module.exports = function (api) {
["babel-preset-expo", { jsxImportSource: "nativewind" }],
"nativewind/babel",
],
plugins: ["react-native-reanimated/plugin"],
};
};

@ -1,5 +1,17 @@
export type Size = "xs" | "md" | "lg" | "xl" | "2xl" | "3xl";
export type Color = "black" | "white" | "orange" | "red";
export type Size =
| "xs"
| "md"
| "lg"
| "xl"
| "2xl"
| "3xl"
| "4xl"
| "5xl"
| "6xl"
| "7xl"
| "8xl"
| "9xl";
export type Color = "black" | "white" | "orange" | "red" | "blue";
export type Weight = "thin" | "normal" | "bold" | "extrabold";
export type Position = "left" | "center" | "right";
@ -17,6 +29,33 @@ export function toTextSize(size: Size): string {
return "text-2xl";
case "3xl":
return "text-3xl";
case "4xl":
return "text-4xl";
case "5xl":
return "text-5xl";
case "6xl":
return "text-6xl";
case "7xl":
return "text-7xl";
case "8xl":
return "text-8xl";
case "9xl":
return "text-9xl";
}
}
export function toBgColor(color: Color): string {
switch (color) {
case "black":
return "bg-black";
case "white":
return "bg-white";
case "orange":
return "bg-orange-500";
case "red":
return "bg-red-500";
case "blue":
return "bg-blue-200";
}
}
@ -30,6 +69,8 @@ export function toTextColor(color: Color): string {
return "text-orange-500";
case "red":
return "text-red-500";
case "blue":
return "text-blue-500";
}
}

@ -0,0 +1,48 @@
import React from "react";
import Question, { QuestionChildProps } from "./Question";
import Slider from "../ui/Slider";
import Text from "../ui/Text";
import { View } from "react-native";
import SegmentedControl from "@react-native-segmented-control/segmented-control";
export default React.forwardRef<any, QuestionChildProps>(
(props, ref): React.ReactElement => {
const MIN_HEIGHT = 120;
const MAX_HEIGHT = 250;
const UNITS = ["cm", "inch"];
const [height, setHeight] = React.useState(MIN_HEIGHT);
const [unit, setUnit] = React.useState("cm");
return (
<Question question="Quel est votre taille ?" {...ref} {...props}>
<SegmentedControl
values={UNITS}
selectedIndex={UNITS.indexOf(unit)}
onValueChange={setUnit}
/>
<View className="flex-row justify-center">
{height <= MIN_HEIGHT ? (
<Text className="mt-8" size="4xl">
- de
</Text>
) : null}
{height >= MAX_HEIGHT ? (
<Text className="mt-8" size="4xl">
+ de
</Text>
) : null}
<Text size="8xl" weight="bold">
{height}
</Text>
<Text className="mt-8" size="4xl">
{unit}
</Text>
</View>
<Slider
minimumValue={MIN_HEIGHT}
maximumValue={MAX_HEIGHT}
onValueChange={setHeight}
/>
</Question>
);
}
);

@ -14,12 +14,12 @@ export default React.forwardRef<any, QuestionProps>(
(props, ref): React.ReactElement => {
const { question, isVisible, children, ...rest } = props;
const getClassName = () => {
return "gap-4" + " " + (isVisible ? "block" : "hidden");
return "gap-6" + " " + (isVisible ? "block" : "hidden");
};
return (
<View className={getClassName()} {...ref} {...rest}>
<Text size="3xl" position="center">
<Text size="4xl" position="center" weight="bold">
{question}
</Text>
{children}

@ -0,0 +1,48 @@
import React from "react";
import Question, { QuestionChildProps } from "./Question";
import Slider from "../ui/Slider";
import Text from "../ui/Text";
import { View } from "react-native";
import SegmentedControl from "@react-native-segmented-control/segmented-control";
export default React.forwardRef<any, QuestionChildProps>(
(props, ref): React.ReactElement => {
const MIN_WEIGHT = 40;
const MAX_WEIGHT = 200;
const UNITS = ["kg", "lb"];
const [weight, setWeight] = React.useState(MIN_WEIGHT);
const [unit, setUnit] = React.useState("kg");
return (
<Question question="Quel est votre poids ?" {...ref} {...props}>
<SegmentedControl
values={UNITS}
selectedIndex={UNITS.indexOf(unit)}
onValueChange={setUnit}
/>
<View className="flex-row justify-center">
{weight <= MIN_WEIGHT ? (
<Text className="mt-8" size="4xl">
- de
</Text>
) : null}
{weight >= MAX_WEIGHT ? (
<Text className="mt-8" size="4xl">
+ de
</Text>
) : null}
<Text size="8xl" weight="bold">
{weight}
</Text>
<Text className="mt-8" size="4xl">
{unit}
</Text>
</View>
<Slider
minimumValue={MIN_WEIGHT}
maximumValue={MAX_WEIGHT}
onValueChange={setWeight}
/>
</Question>
);
}
);

@ -0,0 +1,17 @@
import React from "react";
import SegmentedControl, {
SegmentedControlProps,
} from "@react-native-segmented-control/segmented-control";
export default React.forwardRef<any, SegmentedControlProps>(
(props, ref): React.ReactElement => {
return (
<SegmentedControl
tintColor="#3B82F6"
backgroundColor="#3B82F6"
{...ref}
{...props}
/>
);
}
);

@ -0,0 +1,18 @@
import React from "react";
import Slider, { SliderProps } from "@react-native-community/slider";
export default React.forwardRef<any, SliderProps>(
(props, ref): React.ReactElement => {
const { ...rest } = props;
return (
<Slider
step={1}
thumbTintColor="#F97316"
minimumTrackTintColor="#F97316"
maximumTrackTintColor="#F97316"
{...ref}
{...rest}
/>
);
}
);

181
package-lock.json generated

@ -10,6 +10,8 @@
"dependencies": {
"@expo/html-elements": "^0.4.2",
"@expo/vector-icons": "^14.0.2",
"@react-native-community/slider": "^4.5.5",
"@react-native-segmented-control/segmented-control": "^2.5.7",
"@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native": "^7.0.14",
"@react-navigation/native-stack": "^7.2.0",
@ -37,7 +39,7 @@
"react-native": "0.76.6",
"react-native-gesture-handler": "^2.20.2",
"react-native-gifted-charts": "^1.4.54",
"react-native-reanimated": "~3.16.1",
"react-native-reanimated": "^3.16.7",
"react-native-safe-area-context": "4.12.0",
"react-native-screens": "^4.4.0",
"react-native-svg": "15.8.0",
@ -1137,9 +1139,9 @@
}
},
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.5.tgz",
"integrity": "sha512-OHqczNm4NTQlW1ghrVY43FPoiRzbmzNVbcgVnMKZN/RQYezHUSdjACjaX50CD3B7UIAjv39+MlsrVDb3v741FA==",
"version": "7.26.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz",
"integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==",
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.26.5"
@ -1703,9 +1705,9 @@
}
},
"node_modules/@expo/cli": {
"version": "0.22.9",
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.22.9.tgz",
"integrity": "sha512-GFW1+InbgTz0+10qWfoo5fyBU2DhhPuJkL4TUnG7GTq8lDlim88JLghJVbq0uAX/xDLcd326QnI0XONsUGSWrw==",
"version": "0.22.10",
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.22.10.tgz",
"integrity": "sha512-MA4TOtf6x8ixVaQbUINgest/DsrWcMVGMmjXYtnhUfwQGvZtJC+aI+xMBM7ow2OqY2B/xfoRcgqkvWkl36yxkA==",
"license": "MIT",
"dependencies": {
"@0no-co/graphql.web": "^1.0.8",
@ -1764,7 +1766,7 @@
"requireg": "^0.2.2",
"resolve": "^1.22.2",
"resolve-from": "^5.0.0",
"resolve.exports": "^2.0.2",
"resolve.exports": "^2.0.3",
"semver": "^7.6.0",
"send": "^0.19.0",
"slugify": "^1.3.4",
@ -1964,9 +1966,9 @@
}
},
"node_modules/@expo/html-elements": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@expo/html-elements/-/html-elements-0.4.2.tgz",
"integrity": "sha512-lNioCgdtOrCMMqzHY+PCTdyuWBTU4yMBlOzPSkS4YFIWt9bq0zexM2ZJkpybTXmowNdE3zHO93xxAmiA2yDi2w==",
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/@expo/html-elements/-/html-elements-0.4.3.tgz",
"integrity": "sha512-UwEEdnpyhUEIDe/AkFSBUmCuwcknjAuu73fd5L9Rm/BbHczYXCrtyZmzCNVBsAiHhwUjmhNWzFlr9cAkp/sxIA==",
"license": "MIT"
},
"node_modules/@expo/image-utils": {
@ -2127,9 +2129,9 @@
}
},
"node_modules/@expo/metro-runtime": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-4.0.0.tgz",
"integrity": "sha512-+zgCyuXqIzgZVN8h0g36sursGXBy3xqtJW9han7t/iR2HTTrrbEoep5ftW1a27bdSINU96ng+rSsPLbyHYeBvw==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-4.0.1.tgz",
"integrity": "sha512-CRpbLvdJ1T42S+lrYa1iZp1KfDeBp4oeZOK3hdpiS5n0vR0nhD6sC1gGF0sTboCTp64tLteikz5Y3j53dvgOIw==",
"license": "MIT",
"peerDependencies": {
"react-native": "*"
@ -2278,9 +2280,9 @@
"license": "MIT"
},
"node_modules/@expo/server": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@expo/server/-/server-0.5.0.tgz",
"integrity": "sha512-bfo5udr9C2feCn+vGQ9LvjRD2zFjMyBEnMWDZLYr5D8eCjqLjazGBpPKOVjWOhFR2SshKA3hUBkWEYrVpun0NQ==",
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/@expo/server/-/server-0.5.1.tgz",
"integrity": "sha512-lk8pKKw0eVP6rqkDR46vQB3vLA46z4KNGrqHpjD/SvMu1cGaRmQG2cQdX44mQtG8WyO9EYau+fBMHQQS2OTFKg==",
"license": "MIT",
"dependencies": {
"@remix-run/node": "^2.12.0",
@ -3002,6 +3004,22 @@
"react": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@react-native-community/slider": {
"version": "4.5.5",
"resolved": "https://registry.npmjs.org/@react-native-community/slider/-/slider-4.5.5.tgz",
"integrity": "sha512-x2N415pg4ZxIltArOKczPwn7JEYh+1OxQ4+hTnafomnMsqs65HZuEWcX+Ch8c5r8V83DiunuQUf5hWGWlw8hQQ==",
"license": "MIT"
},
"node_modules/@react-native-segmented-control/segmented-control": {
"version": "2.5.7",
"resolved": "https://registry.npmjs.org/@react-native-segmented-control/segmented-control/-/segmented-control-2.5.7.tgz",
"integrity": "sha512-l84YeVX8xAU3lvOJSvV4nK/NbGhIm2gBfveYolwaoCbRp+/SLXtc6mYrQmM9ScXNwU14mnzjQTpTHWl5YPnkzQ==",
"license": "MIT",
"peerDependencies": {
"react": ">=16.0",
"react-native": ">=0.62"
}
},
"node_modules/@react-native/assets-registry": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.6.tgz",
@ -4187,9 +4205,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.10.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz",
"integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==",
"version": "22.10.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz",
"integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.20.0"
@ -5223,9 +5241,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001692",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz",
"integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==",
"version": "1.0.30001695",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001695.tgz",
"integrity": "sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==",
"funding": [
{
"type": "opencollective",
@ -6359,9 +6377,9 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
"version": "1.5.80",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.80.tgz",
"integrity": "sha512-LTrKpW0AqIuHwmlVNV+cjFYTnXtM9K37OGhpe0ZI10ScPSxqVSryZHIY3WnCS5NSYbBODRTZyhRMS2h5FAEqAw==",
"version": "1.5.84",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.84.tgz",
"integrity": "sha512-I+DQ8xgafao9Ha6y0qjHHvpZ9OfyA1qKlkHkjywxzniORU2awxyz7f/iVJcULmrF2yrM3nHQf+iDjJtbbexd/g==",
"license": "ISC"
},
"node_modules/emittery": {
@ -6465,9 +6483,9 @@
}
},
"node_modules/es-object-atoms": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
"integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
@ -6711,13 +6729,13 @@
}
},
"node_modules/expo": {
"version": "52.0.25",
"resolved": "https://registry.npmjs.org/expo/-/expo-52.0.25.tgz",
"integrity": "sha512-BWHveMyDSST7vuGNn8zbrSGboJdvXDE9auUEkFa14ETAWRtsghYnZ0KmjOEQNxNmrBHzct/JgZ8efh5sJGd0xA==",
"version": "52.0.27",
"resolved": "https://registry.npmjs.org/expo/-/expo-52.0.27.tgz",
"integrity": "sha512-PxIS8JRTegUNYq4vNeP0eCqm7p17oGNYjJ/9x207zkwVlklywD9LYIckGojXEY5JPW/DwhbhtO6E2hMgdQQugg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.20.0",
"@expo/cli": "0.22.9",
"@expo/cli": "0.22.10",
"@expo/config": "~10.0.8",
"@expo/config-plugins": "~9.0.14",
"@expo/fingerprint": "0.11.7",
@ -6729,8 +6747,8 @@
"expo-file-system": "~18.0.7",
"expo-font": "~13.0.3",
"expo-keep-awake": "~14.0.2",
"expo-modules-autolinking": "2.0.5",
"expo-modules-core": "2.1.3",
"expo-modules-autolinking": "2.0.7",
"expo-modules-core": "2.1.4",
"fbemitter": "^3.0.0",
"web-streams-polyfill": "^3.3.2",
"whatwg-url-without-unicode": "8.0.0-3"
@ -6870,9 +6888,9 @@
}
},
"node_modules/expo-modules-autolinking": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.0.5.tgz",
"integrity": "sha512-z1aAa7OtnAXZRFwn/CSgr9qSclW0mepGRJzcjZjyHL49u3VWmAHaPLl6S5vVGSX3sTYsFjKJ7ioCCye3tNdeUg==",
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.0.7.tgz",
"integrity": "sha512-rkGc6a/90AC3q8wSy4V+iIpq6Fd0KXmQICKrvfmSWwrMgJmLfwP4QTrvLYPYOOMjFwNJcTaohcH8vzW/wYKrMg==",
"license": "MIT",
"dependencies": {
"@expo/spawn-async": "^1.7.2",
@ -6925,22 +6943,22 @@
}
},
"node_modules/expo-modules-core": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.1.3.tgz",
"integrity": "sha512-DkSEr7q/SobjmCAo70833+xl0liShEFDHuC/YzXmHoDRxYHJaZCNc9uVBqjMeRfPVWp+4Rj9hF/gNvfad7vy0g==",
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.1.4.tgz",
"integrity": "sha512-gfsbTPSaocgcQQDy4Z4ztg1hcOofwODctAA+yoNcrUQr/hRaDc6ndIJQwGPjoGXnEbXVxFfzGGSAkNiqK1I7lQ==",
"license": "MIT",
"dependencies": {
"invariant": "^2.2.4"
}
},
"node_modules/expo-router": {
"version": "4.0.16",
"resolved": "https://registry.npmjs.org/expo-router/-/expo-router-4.0.16.tgz",
"integrity": "sha512-KRGUxo43g9gCWbq9cJn5AkxW+rOxoJwBNv3X57Ylns5j/5p6WUMiKnRJOT4k8wmMQTQGzH37gGDx3ufI2A9Q2g==",
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/expo-router/-/expo-router-4.0.17.tgz",
"integrity": "sha512-8ybo6bVwdG1S9hafh9BTOjX1hpCgomdUvs6hKHMM01koo8mQ7zocH/+zxQeaMVDxGhboz2dO5GiDchWJ0OheRA==",
"license": "MIT",
"dependencies": {
"@expo/metro-runtime": "4.0.0",
"@expo/server": "^0.5.0",
"@expo/metro-runtime": "4.0.1",
"@expo/server": "^0.5.1",
"@radix-ui/react-slot": "1.0.1",
"@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native": "^7.0.14",
@ -6996,9 +7014,9 @@
}
},
"node_modules/expo-splash-screen": {
"version": "0.29.20",
"resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.29.20.tgz",
"integrity": "sha512-6CkKHyfPREhTL4/NcAI1BQqAMo+qv8K5Kt1s+jQCE8LCweX203BWMDYPu5padBnlYfVDAs7O4CFAe3cyaEDSjA==",
"version": "0.29.21",
"resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.29.21.tgz",
"integrity": "sha512-7uZ+qvIuNcvrvrLIklW+Wbt6llPuCj6LKYjrMu+GOX8s///laldS4TGiMAbqcE7fmfCzQ8ffgfY7xhxRourhcA==",
"license": "MIT",
"dependencies": {
"@expo/prebuild-config": "^8.0.25"
@ -7100,9 +7118,9 @@
"license": "MIT"
},
"node_modules/fast-uri": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz",
"integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==",
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
"integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
"funding": [
{
"type": "github",
@ -7364,9 +7382,9 @@
"license": "MIT"
},
"node_modules/flow-parser": {
"version": "0.258.1",
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.258.1.tgz",
"integrity": "sha512-Y8CrO98EcXVCiYE4s5z0LTMbeYjKyd3MAEUJqxA7B8yGRlmdrG5UDqq4pVrUAfAu2tMFgpQESvBhBu9Xg1tpow==",
"version": "0.259.1",
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.259.1.tgz",
"integrity": "sha512-xiXLmMH2Z7OmdE9Q+MjljUMr/rbemFqZIRxaeZieVScG4HzQrKKhNcCYZbWTGpoN7ZPi7z8ClQbeVPq6t5AszQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
@ -7585,9 +7603,9 @@
}
},
"node_modules/gifted-charts-core": {
"version": "0.1.56",
"resolved": "https://registry.npmjs.org/gifted-charts-core/-/gifted-charts-core-0.1.56.tgz",
"integrity": "sha512-Gey9dxjUB4/4bCin+xSyLuudSoBffJ9GK1qd0epBd3vrjHMGYrKFNRlkxI5MRxIJjvTcWOL2Fi43glNC2gs/0w==",
"version": "0.1.57",
"resolved": "https://registry.npmjs.org/gifted-charts-core/-/gifted-charts-core-0.1.57.tgz",
"integrity": "sha512-bXV46FsGwZZtrT7jo9vMrAzYNAc6HOlFhPRwfZlqOiYF+qZAzEyQf1/r2eMe7OTCxUQ9sejR+65PIRhshTnrlw==",
"license": "MIT",
"peerDependencies": {
"react": "*",
@ -8342,6 +8360,12 @@
"node": ">=8"
}
},
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"license": "MIT"
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -12224,15 +12248,14 @@
}
},
"node_modules/react-native-gesture-handler": {
"version": "2.20.2",
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.20.2.tgz",
"integrity": "sha512-HqzFpFczV4qCnwKlvSAvpzEXisL+Z9fsR08YV5LfJDkzuArMhBu2sOoSPUF/K62PCoAb+ObGlTC83TKHfUd0vg==",
"version": "2.22.0",
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.22.0.tgz",
"integrity": "sha512-m5Ps1cOSxSiMP4re+XsbeWcC9DNJuIEjMSmtUxBdyfYEJtdu5iAAiX7KlHHrf2mnK4I/56Ncy4PvPKWBwSpWpQ==",
"license": "MIT",
"dependencies": {
"@egjs/hammerjs": "^2.0.17",
"hoist-non-react-statics": "^3.3.0",
"invariant": "^2.2.4",
"prop-types": "^15.7.2"
"invariant": "^2.2.4"
},
"peerDependencies": {
"react": "*",
@ -12240,12 +12263,12 @@
}
},
"node_modules/react-native-gifted-charts": {
"version": "1.4.54",
"resolved": "https://registry.npmjs.org/react-native-gifted-charts/-/react-native-gifted-charts-1.4.54.tgz",
"integrity": "sha512-FvDRbymuJMxpsPbveQqyLUIYzfgJeY6xC6hNYD0d1OLZdnv/HgNYFMIwpoh2Hv25GRS0BXwPLjf8zE0f2zY9Wg==",
"version": "1.4.55",
"resolved": "https://registry.npmjs.org/react-native-gifted-charts/-/react-native-gifted-charts-1.4.55.tgz",
"integrity": "sha512-WOF5MnCbfqvweY+aUHWalWUBVdOcfHeUQmnVekrNebJrzBzM333WGPItOahDluO8XFVzBoagpow54enBfCbc6w==",
"license": "MIT",
"dependencies": {
"gifted-charts-core": "0.1.56"
"gifted-charts-core": "0.1.57"
},
"peerDependencies": {
"expo-linear-gradient": "*",
@ -12288,9 +12311,9 @@
}
},
"node_modules/react-native-reanimated": {
"version": "3.16.6",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.16.6.tgz",
"integrity": "sha512-jPbAfLF5t8+UCKFTO+LeOY+OmAcDP5SsAfqINvNQz5GFGvoO7UebxujjtY58CmpZNH6c3SQ514FF9//mZDpo/g==",
"version": "3.16.7",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.16.7.tgz",
"integrity": "sha512-qoUUQOwE1pHlmQ9cXTJ2MX9FQ9eHllopCLiWOkDkp6CER95ZWeXhJCP4cSm6AD4jigL5jHcZf/SkWrg8ttZUsw==",
"license": "MIT",
"dependencies": {
"@babel/plugin-transform-arrow-functions": "^7.0.0-0",
@ -12322,9 +12345,9 @@
}
},
"node_modules/react-native-screens": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.4.0.tgz",
"integrity": "sha512-c7zc7Zwjty6/pGyuuvh9gK3YBYqHPOxrhXfG1lF4gHlojQSmIx2piNbNaV+Uykj+RDTmFXK0e/hA+fucw/Qozg==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.5.0.tgz",
"integrity": "sha512-yBWeN5EHNeew9f0ia9VE7JSlUQzCZEwkb87r7A7/Sg41OJHuRKHNRhmdCOiMBUqwwQi3F+b4NZGywjeM/gWMyg==",
"license": "MIT",
"dependencies": {
"react-freeze": "^1.0.0",
@ -12677,12 +12700,6 @@
"util-deprecate": "~1.0.1"
}
},
"node_modules/readable-stream/node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"license": "MIT"
},
"node_modules/readable-stream/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@ -14522,9 +14539,9 @@
}
},
"node_modules/undici": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz",
"integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==",
"version": "6.21.1",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz",
"integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==",
"license": "MIT",
"engines": {
"node": ">=18.17"

@ -17,6 +17,8 @@
"dependencies": {
"@expo/html-elements": "^0.4.2",
"@expo/vector-icons": "^14.0.2",
"@react-native-community/slider": "^4.5.5",
"@react-native-segmented-control/segmented-control": "^2.5.7",
"@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native": "^7.0.14",
"@react-navigation/native-stack": "^7.2.0",
@ -44,7 +46,7 @@
"react-native": "0.76.6",
"react-native-gesture-handler": "^2.20.2",
"react-native-gifted-charts": "^1.4.54",
"react-native-reanimated": "~3.16.1",
"react-native-reanimated": "^3.16.7",
"react-native-safe-area-context": "4.12.0",
"react-native-screens": "^4.4.0",
"react-native-svg": "15.8.0",

@ -1,186 +0,0 @@
"use client";
import React from "react";
import { createAvatar } from "@gluestack-ui/avatar";
import { View, Text, Image, Platform } from "react-native";
import { tva } from "@gluestack-ui/nativewind-utils/tva";
import {
withStyleContext,
useStyleContext,
} from "@gluestack-ui/nativewind-utils/withStyleContext";
import type { VariantProps } from "@gluestack-ui/nativewind-utils";
const SCOPE = "AVATAR";
const UIAvatar = createAvatar({
Root: withStyleContext(View, SCOPE),
Badge: View,
Group: View,
Image: Image,
FallbackText: Text,
});
const avatarStyle = tva({
base: "rounded-full justify-center items-center relative bg-primary-600 group-[.avatar-group]/avatar-group:-ml-2.5",
variants: {
size: {
xs: "w-6 h-6",
sm: "w-8 h-8",
md: "w-12 h-12",
lg: "w-16 h-16",
xl: "w-24 h-24",
"2xl": "w-32 h-32",
},
},
});
const avatarFallbackTextStyle = tva({
base: "text-typography-0 font-semibold overflow-hidden text-transform:uppercase web:cursor-default",
parentVariants: {
size: {
xs: "text-2xs",
sm: "text-xs",
md: "text-base",
lg: "text-xl",
xl: "text-3xl",
"2xl": "text-5xl",
},
},
});
const avatarGroupStyle = tva({
base: "group/avatar-group flex-row-reverse relative avatar-group",
});
const avatarBadgeStyle = tva({
base: "w-5 h-5 bg-success-500 rounded-full absolute right-0 bottom-0 border-background-0 border-2",
parentVariants: {
size: {
xs: "w-2 h-2",
sm: "w-2 h-2",
md: "w-3 h-3",
lg: "w-4 h-4",
xl: "w-6 h-6",
"2xl": "w-8 h-8",
},
},
});
const avatarImageStyle = tva({
base: "h-full w-full rounded-full absolute",
});
type IAvatarProps = Omit<
React.ComponentPropsWithoutRef<typeof UIAvatar>,
"context"
> &
VariantProps<typeof avatarStyle>;
const Avatar = React.forwardRef<
React.ElementRef<typeof UIAvatar>,
IAvatarProps
>(({ className, size = "md", ...props }, ref) => {
return (
<UIAvatar
ref={ref}
{...props}
className={avatarStyle({ size, class: className })}
context={{ size }}
/>
);
});
type IAvatarBadgeProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Badge> &
VariantProps<typeof avatarBadgeStyle>;
const AvatarBadge = React.forwardRef<
React.ElementRef<typeof UIAvatar.Badge>,
IAvatarBadgeProps
>(({ className, size, ...props }, ref) => {
const { size: parentSize } = useStyleContext(SCOPE);
return (
<UIAvatar.Badge
ref={ref}
{...props}
className={avatarBadgeStyle({
parentVariants: {
size: parentSize,
},
size,
class: className,
})}
/>
);
});
type IAvatarFallbackTextProps = React.ComponentPropsWithoutRef<
typeof UIAvatar.FallbackText
> &
VariantProps<typeof avatarFallbackTextStyle>;
const AvatarFallbackText = React.forwardRef<
React.ElementRef<typeof UIAvatar.FallbackText>,
IAvatarFallbackTextProps
>(({ className, size, ...props }, ref) => {
const { size: parentSize } = useStyleContext(SCOPE);
return (
<UIAvatar.FallbackText
ref={ref}
{...props}
className={avatarFallbackTextStyle({
parentVariants: {
size: parentSize,
},
size,
class: className,
})}
/>
);
});
type IAvatarImageProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Image> &
VariantProps<typeof avatarImageStyle>;
const AvatarImage = React.forwardRef<
React.ElementRef<typeof UIAvatar.Image>,
IAvatarImageProps
>(({ className, ...props }, ref) => {
return (
<UIAvatar.Image
ref={ref}
{...props}
className={avatarImageStyle({
class: className,
})}
// @ts-expect-error
style={
Platform.OS === "web"
? // eslint-disable-next-line react-native/no-inline-styles
{ height: "revert-layer", width: "revert-layer" }
: undefined
}
/>
);
});
type IAvatarGroupProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Group> &
VariantProps<typeof avatarGroupStyle>;
const AvatarGroup = React.forwardRef<
React.ElementRef<typeof UIAvatar.Group>,
IAvatarGroupProps
>(({ className, ...props }, ref) => {
return (
<UIAvatar.Group
ref={ref}
{...props}
className={avatarGroupStyle({
class: className,
})}
/>
);
});
export { Avatar, AvatarBadge, AvatarFallbackText, AvatarImage, AvatarGroup };

@ -1,237 +0,0 @@
'use client';
import React from 'react';
import { createCheckbox } from '@gluestack-ui/checkbox';
import { View, Pressable, Text, Platform } from 'react-native';
import type { TextProps, ViewProps } from 'react-native';
import { tva } from '@gluestack-ui/nativewind-utils/tva';
import { PrimitiveIcon, IPrimitiveIcon, UIIcon } from '@gluestack-ui/icon';
import {
withStyleContext,
useStyleContext,
} from '@gluestack-ui/nativewind-utils/withStyleContext';
import { cssInterop } from 'nativewind';
import type { VariantProps } from '@gluestack-ui/nativewind-utils';
const IndicatorWrapper = React.forwardRef<
React.ElementRef<typeof View>,
ViewProps
>(({ ...props }, ref) => {
return <View {...props} ref={ref} />;
});
const LabelWrapper = React.forwardRef<React.ElementRef<typeof Text>, TextProps>(
({ ...props }, ref) => {
return <Text {...props} ref={ref} />;
}
);
const IconWrapper = React.forwardRef<
React.ElementRef<typeof PrimitiveIcon>,
IPrimitiveIcon
>(({ ...props }, ref) => {
return <UIIcon {...props} ref={ref} />;
});
const SCOPE = 'CHECKBOX';
const UICheckbox = createCheckbox({
// @ts-expect-error
Root:
Platform.OS === 'web'
? withStyleContext(View, SCOPE)
: withStyleContext(Pressable, SCOPE),
Group: View,
Icon: IconWrapper,
Label: LabelWrapper,
Indicator: IndicatorWrapper,
});
cssInterop(PrimitiveIcon, {
className: {
target: 'style',
nativeStyleToProp: {
height: true,
width: true,
fill: true,
color: 'classNameColor',
stroke: true,
},
},
});
const checkboxStyle = tva({
base: 'group/checkbox flex-row items-center justify-start web:cursor-pointer data-[disabled=true]:cursor-not-allowed',
variants: {
size: {
lg: 'gap-2',
md: 'gap-2',
sm: 'gap-1.5',
},
},
});
const checkboxIndicatorStyle = tva({
base: 'justify-center items-center border-outline-400 bg-transparent rounded web:data-[focus-visible=true]:outline-none web:data-[focus-visible=true]:ring-2 web:data-[focus-visible=true]:ring-indicator-primary data-[checked=true]:bg-primary-600 data-[checked=true]:border-primary-600 data-[hover=true]:data-[checked=false]:border-outline-500 data-[hover=true]:bg-transparent data-[hover=true]:data-[invalid=true]:border-error-700 data-[hover=true]:data-[checked=true]:bg-primary-700 data-[hover=true]:data-[checked=true]:border-primary-700 data-[hover=true]:data-[checked=true]:data-[disabled=true]:border-primary-600 data-[hover=true]:data-[checked=true]:data-[disabled=true]:bg-primary-600 data-[hover=true]:data-[checked=true]:data-[disabled=true]:opacity-40 data-[hover=true]:data-[checked=true]:data-[disabled=true]:data-[invalid=true]:border-error-700 data-[hover=true]:data-[disabled=true]:border-outline-400 data-[hover=true]:data-[disabled=true]:data-[invalid=true]:border-error-700 data-[active=true]:data-[checked=true]:bg-primary-800 data-[active=true]:data-[checked=true]:border-primary-800 data-[invalid=true]:border-error-700 data-[disabled=true]:opacity-40',
parentVariants: {
size: {
lg: 'w-6 h-6 border-[3px]',
md: 'w-5 h-5 border-2',
sm: 'w-4 h-4 border-2',
},
},
});
const checkboxLabelStyle = tva({
base: 'text-typography-600 data-[checked=true]:text-typography-900 data-[hover=true]:text-typography-900 data-[hover=true]:data-[checked=true]:text-typography-900 data-[hover=true]:data-[checked=true]:data-[disabled=true]:text-typography-900 data-[hover=true]:data-[disabled=true]:text-typography-400 data-[active=true]:text-typography-900 data-[active=true]:data-[checked=true]:text-typography-900 data-[disabled=true]:opacity-40 web:select-none',
parentVariants: {
size: {
lg: 'text-lg',
md: 'text-base',
sm: 'text-sm',
},
},
});
const checkboxIconStyle = tva({
base: 'text-typography-50 fill-none',
parentVariants: {
size: {
sm: 'h-3 w-3',
md: 'h-4 w-4',
lg: 'h-5 w-5',
},
},
});
const CheckboxGroup = UICheckbox.Group;
type ICheckboxProps = React.ComponentPropsWithoutRef<typeof UICheckbox> &
VariantProps<typeof checkboxStyle>;
const Checkbox = React.forwardRef<
React.ElementRef<typeof UICheckbox>,
ICheckboxProps
>(({ className, size = 'md', ...props }, ref) => {
return (
<UICheckbox
className={checkboxStyle({
class: className,
size,
})}
{...props}
context={{
size,
}}
ref={ref}
/>
);
});
type ICheckboxIndicatorProps = React.ComponentPropsWithoutRef<
typeof UICheckbox.Indicator
> &
VariantProps<typeof checkboxIndicatorStyle>;
const CheckboxIndicator = React.forwardRef<
React.ElementRef<typeof UICheckbox.Indicator>,
ICheckboxIndicatorProps
>(({ className, ...props }, ref) => {
const { size: parentSize } = useStyleContext(SCOPE);
return (
<UICheckbox.Indicator
className={checkboxIndicatorStyle({
parentVariants: {
size: parentSize,
},
class: className,
})}
{...props}
ref={ref}
/>
);
});
type ICheckboxLabelProps = React.ComponentPropsWithoutRef<
typeof UICheckbox.Label
> &
VariantProps<typeof checkboxLabelStyle>;
const CheckboxLabel = React.forwardRef<
React.ElementRef<typeof UICheckbox.Label>,
ICheckboxLabelProps
>(({ className, ...props }, ref) => {
const { size: parentSize } = useStyleContext(SCOPE);
return (
<UICheckbox.Label
className={checkboxLabelStyle({
parentVariants: {
size: parentSize,
},
class: className,
})}
{...props}
ref={ref}
/>
);
});
type ICheckboxIconProps = React.ComponentPropsWithoutRef<
typeof UICheckbox.Icon
> &
VariantProps<typeof checkboxIconStyle>;
const CheckboxIcon = React.forwardRef<
React.ElementRef<typeof UICheckbox.Icon>,
ICheckboxIconProps
>(({ className, size, ...props }, ref) => {
const { size: parentSize } = useStyleContext(SCOPE);
if (typeof size === 'number') {
return (
<UICheckbox.Icon
ref={ref}
{...props}
className={checkboxIconStyle({ class: className })}
size={size}
/>
);
} else if (
(props.height !== undefined || props.width !== undefined) &&
size === undefined
) {
return (
<UICheckbox.Icon
ref={ref}
{...props}
className={checkboxIconStyle({ class: className })}
/>
);
}
return (
<UICheckbox.Icon
className={checkboxIconStyle({
parentVariants: {
size: parentSize,
},
class: className,
size,
})}
{...props}
ref={ref}
/>
);
});
Checkbox.displayName = 'Checkbox';
CheckboxIndicator.displayName = 'CheckboxIndicator';
CheckboxLabel.displayName = 'CheckboxLabel';
CheckboxIcon.displayName = 'CheckboxIcon';
export {
Checkbox,
CheckboxIndicator,
CheckboxLabel,
CheckboxIcon,
CheckboxGroup,
};
Loading…
Cancel
Save