fln-espranza 1.1.18 → 1.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.expo/README.md +15 -15
- package/.expo/settings.json +8 -8
- package/assets/images/bg-profile.jpg +0 -0
- package/assets/images/bg-stat.png +0 -0
- package/assets/images/empty.png +0 -0
- package/assets/images/icon-placeholder-schedule.png +0 -0
- package/components/Avatar.tsx +3 -2
- package/components/Drawer.tsx +150 -97
- package/components/EBadge.tsx +50 -19
- package/components/EButton.tsx +10 -15
- package/components/EButtonIcon.tsx +3 -3
- package/components/EDateAndTimeCard.tsx +18 -17
- package/components/EDateInput.tsx +15 -14
- package/components/EEmptyPlaceholder.tsx +21 -0
- package/components/EInfoBox.tsx +3 -3
- package/components/EInput.tsx +7 -6
- package/components/ELabel.tsx +1 -1
- package/components/EListClusterMeeting.tsx +47 -0
- package/components/EListPerson.tsx +30 -10
- package/components/EListSchool.tsx +2 -2
- package/components/ENotFoundPlaceholder.tsx +43 -0
- package/components/EOption.tsx +98 -0
- package/components/EPageDescription.tsx +1 -2
- package/components/EPillButton.tsx +24 -17
- package/components/EProfile.tsx +40 -26
- package/components/EProfileScreenLayout.tsx +111 -0
- package/components/EProgressBar.tsx +47 -0
- package/components/EQuestionSerialNumberLabel.tsx +17 -0
- package/components/EQuestionText.tsx +14 -0
- package/components/EStat.tsx +44 -0
- package/components/EStatReport.tsx +49 -0
- package/components/EText.tsx +2 -1
- package/components/ETextArea.tsx +53 -0
- package/components/ETimeInput.tsx +3 -4
- package/components/ETimeLineCard.tsx +29 -29
- package/components/MenuItems.tsx +1 -1
- package/components/ModalLayout.tsx +13 -12
- package/components/PageHeader.tsx +66 -73
- package/components/PageHeaderSecondary.tsx +4 -2
- package/components/ProfileHeader.tsx +85 -0
- package/components/SecondaryBaseLayout.tsx +41 -44
- package/components/icons/EIconAdd.jsx +19 -0
- package/components/icons/EIconAddCircle.jsx +21 -0
- package/components/icons/EIconApplicationStatus.jsx +20 -0
- package/components/icons/EIconArrowDown.jsx +20 -0
- package/components/icons/EIconArrowLeft.jsx +21 -0
- package/components/icons/EIconArrowRight.jsx +21 -0
- package/components/icons/EIconArrowUp.jsx +20 -0
- package/components/icons/EIconBadge.jsx +20 -0
- package/components/icons/EIconBell.jsx +19 -0
- package/components/icons/EIconCalendar.jsx +21 -0
- package/components/icons/EIconCalendarCheck.jsx +24 -0
- package/components/icons/EIconCamera.jsx +20 -0
- package/components/icons/EIconCameraRotate.jsx +23 -0
- package/components/icons/EIconCheck.jsx +19 -0
- package/components/icons/EIconCheckCircle.jsx +20 -0
- package/components/icons/EIconCheckFill.jsx +19 -0
- package/components/icons/EIconChevronDown.jsx +19 -0
- package/components/icons/EIconChevronLeft.jsx +19 -0
- package/components/icons/EIconChevronRight.jsx +19 -0
- package/components/icons/EIconChevronUp.jsx +19 -0
- package/components/icons/EIconClock.jsx +19 -0
- package/components/icons/EIconClose.jsx +19 -0
- package/components/icons/EIconDashboard.jsx +20 -0
- package/components/icons/EIconDocumentCheck.jsx +14 -0
- package/components/icons/EIconEdit.jsx +19 -0
- package/components/icons/EIconFemale.jsx +20 -0
- package/components/icons/EIconFile.jsx +21 -0
- package/components/icons/EIconInfo.jsx +20 -0
- package/components/icons/EIconLogout.jsx +19 -0
- package/components/icons/EIconMale.jsx +21 -0
- package/components/icons/EIconMenu.jsx +19 -0
- package/components/icons/EIconMinus.jsx +19 -0
- package/components/icons/EIconPin.jsx +19 -0
- package/components/icons/EIconProfile.jsx +19 -0
- package/components/icons/EIconSchool.jsx +24 -0
- package/components/icons/EIconSearch.jsx +19 -0
- package/components/icons/EIconSettings.jsx +20 -0
- package/components/icons/EIconShare.jsx +21 -0
- package/components/icons/EIconStudent.jsx +24 -0
- package/components/icons/EIconSubject.jsx +21 -0
- package/components/icons/EIconTeach.jsx +21 -0
- package/components/icons/EIconTrash.jsx +19 -0
- package/components/icons/EIconUserCard.jsx +19 -0
- package/components/icons/EIconUserCheck.jsx +20 -0
- package/components/icons/EIconUsers.jsx +19 -0
- package/components/index.tsx +5 -1
- package/index.ts +185 -72
- package/lib/tailwind.js +7 -7
- package/lib/useChangeLanguage.ts +60 -0
- package/package.json +26 -26
- package/tailwind.config.js +32 -32
- package/utils/Color.ts +14 -14
- package/components/ProgressBar.tsx +0 -33
package/components/EInfoBox.tsx
CHANGED
|
@@ -22,16 +22,16 @@ export default function InfoBox({
|
|
|
22
22
|
childTextColor,
|
|
23
23
|
}: InfoBoxProps) {
|
|
24
24
|
return (
|
|
25
|
-
<View style={[tw.style("rounded-lg"), style]}>
|
|
25
|
+
<View style={[tw.style("rounded-lg bg-blue-500/10 border border-blue-800/10 p-4"), style]}>
|
|
26
26
|
<View style={tw`flex-row`}>
|
|
27
|
-
<View style={tw`w-5 h-5 mr-
|
|
27
|
+
<View style={tw`w-5 h-5 mr-2`}>{icon}</View>
|
|
28
28
|
<View style={tw`flex-1`}>
|
|
29
29
|
{title ? (
|
|
30
30
|
<EText size="sm" style={tw`font-semibold mb-1 text-${color ? color : "white"}`}>
|
|
31
31
|
{title}
|
|
32
32
|
</EText>
|
|
33
33
|
) : null}
|
|
34
|
-
<EText size="xs" style={[tw`
|
|
34
|
+
<EText size="xs" style={[tw`text-slate-900 opacity-70`, {color: childTextColor}]}>
|
|
35
35
|
{children}
|
|
36
36
|
</EText>
|
|
37
37
|
</View>
|
package/components/EInput.tsx
CHANGED
|
@@ -10,6 +10,7 @@ interface EInputProps extends TextInputProps {
|
|
|
10
10
|
size?: "lg";
|
|
11
11
|
hasBackground?: boolean;
|
|
12
12
|
icon?: JSX.Element;
|
|
13
|
+
style?: any;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export default function EInput({
|
|
@@ -17,25 +18,25 @@ export default function EInput({
|
|
|
17
18
|
size,
|
|
18
19
|
hasBackground,
|
|
19
20
|
icon,
|
|
21
|
+
style,
|
|
20
22
|
...props
|
|
21
23
|
}: EInputProps) {
|
|
22
24
|
const [hasFocus, setHasFocus] = useState(false);
|
|
23
25
|
return (
|
|
24
|
-
<View style={[tw`mb-4`, {}]}>
|
|
26
|
+
<View style={[tw`mb-4`, {style}]}>
|
|
25
27
|
{label ? (
|
|
26
|
-
<EText
|
|
27
|
-
// color: Colors["text-primary"]
|
|
28
|
+
<EText style={[tw`font-semibold ${hasFocus ? '' : 'text-slate-800'}`, {
|
|
28
29
|
}]}>
|
|
29
30
|
{label}
|
|
30
31
|
</EText>
|
|
31
32
|
) : null}
|
|
32
33
|
|
|
33
34
|
<View
|
|
34
|
-
style={tw` mt-
|
|
35
|
+
style={tw` mt-1`}
|
|
35
36
|
>
|
|
36
37
|
<TextInput
|
|
37
|
-
style={tw`h-12 rounded-lg px-4 flex-row items-center border border-slate-300 ${
|
|
38
|
-
hasFocus ? "border-black
|
|
38
|
+
style={tw`h-12 rounded-lg px-4 flex-row items-center border border-slate-300 text-base ${
|
|
39
|
+
hasFocus ? "border-black bg-teal-50/10" : ""
|
|
39
40
|
}`}
|
|
40
41
|
{...props}
|
|
41
42
|
onFocus={() => setHasFocus(!hasFocus)}
|
package/components/ELabel.tsx
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { TouchableOpacity, TouchableOpacityProps, View } from "react-native";
|
|
3
|
+
import tw from "../lib/tailwind";
|
|
4
|
+
import EText from "./EText";
|
|
5
|
+
import { ChevronRightIcon } from "react-native-heroicons/outline";
|
|
6
|
+
import { Colors } from "fln-espranza/utils/Color";
|
|
7
|
+
|
|
8
|
+
interface IProps extends TouchableOpacityProps {
|
|
9
|
+
date: string;
|
|
10
|
+
time: string;
|
|
11
|
+
location: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default function EListClusterMeeting({
|
|
15
|
+
date,
|
|
16
|
+
time,
|
|
17
|
+
location,
|
|
18
|
+
...props
|
|
19
|
+
}: IProps) {
|
|
20
|
+
return (
|
|
21
|
+
<TouchableOpacity
|
|
22
|
+
style={tw`border-b border-slate-200 py-3`}
|
|
23
|
+
{...props}
|
|
24
|
+
activeOpacity={0.5}
|
|
25
|
+
>
|
|
26
|
+
<View style={tw`flex-row items-center`}>
|
|
27
|
+
<EText style={tw`font-bold text-slate-800 mb-0.5 flex-1`}>{date}</EText>
|
|
28
|
+
<ChevronRightIcon style={tw`text-slate-800`} size={16} />
|
|
29
|
+
</View>
|
|
30
|
+
<View style={tw`flex-row flex-1 items-center`}>
|
|
31
|
+
<EText size="sm" style={tw`text-slate-500`}>
|
|
32
|
+
{time}
|
|
33
|
+
</EText>
|
|
34
|
+
<View
|
|
35
|
+
style={tw`w-1 h-1 bg-[${Colors["primary-base"]}] rounded-full mx-2`}
|
|
36
|
+
></View>
|
|
37
|
+
<EText
|
|
38
|
+
size="sm"
|
|
39
|
+
style={tw`text-slate-500 flex-1 pr-6`}
|
|
40
|
+
numberOfLines={1}
|
|
41
|
+
>
|
|
42
|
+
{location}
|
|
43
|
+
</EText>
|
|
44
|
+
</View>
|
|
45
|
+
</TouchableOpacity>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -9,6 +9,8 @@ interface IProps {
|
|
|
9
9
|
subtitle?: string;
|
|
10
10
|
noBorder?: boolean;
|
|
11
11
|
firstLetter?: string;
|
|
12
|
+
itemsEnd?: JSX.Element;
|
|
13
|
+
subTitleIcon?: JSX.Element;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export default function EListPerson({
|
|
@@ -16,24 +18,42 @@ export default function EListPerson({
|
|
|
16
18
|
subtitle,
|
|
17
19
|
noBorder,
|
|
18
20
|
firstLetter,
|
|
21
|
+
itemsEnd,
|
|
22
|
+
subTitleIcon,
|
|
19
23
|
}: IProps) {
|
|
20
24
|
return (
|
|
21
25
|
<View style={[tw`flex-row items-center justify-between`]}>
|
|
22
|
-
<Avatar
|
|
26
|
+
<Avatar
|
|
27
|
+
size="sm"
|
|
28
|
+
source={""}
|
|
29
|
+
nameFirstLetter={name.split(" ")[0].charAt(0)}
|
|
30
|
+
/>
|
|
23
31
|
<View
|
|
24
|
-
style={tw` ml-3 py-3 flex-1 ${
|
|
32
|
+
style={tw` ml-3 py-3 flex-1 flex-row items-center justify-between ${
|
|
25
33
|
noBorder ? "" : "border-b border-slate-200"
|
|
26
34
|
}`}
|
|
27
35
|
>
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
{
|
|
36
|
+
<View>
|
|
37
|
+
<EText
|
|
38
|
+
size="lg"
|
|
39
|
+
style={tw`font-bold text-slate-800 mb-0.5 capitalize`}
|
|
40
|
+
numberOfLines={1}
|
|
41
|
+
>
|
|
42
|
+
{name}
|
|
35
43
|
</EText>
|
|
36
|
-
|
|
44
|
+
|
|
45
|
+
<View style={tw`flex flex-row items-center`}>
|
|
46
|
+
{subTitleIcon ? subTitleIcon : <></>}
|
|
47
|
+
{subtitle ? (
|
|
48
|
+
<EText size="sm" style={tw`text-slate-500`}>
|
|
49
|
+
{subtitle}
|
|
50
|
+
</EText>
|
|
51
|
+
) : (
|
|
52
|
+
<></>
|
|
53
|
+
)}
|
|
54
|
+
</View>
|
|
55
|
+
</View>
|
|
56
|
+
{itemsEnd}
|
|
37
57
|
</View>
|
|
38
58
|
</View>
|
|
39
59
|
);
|
|
@@ -18,11 +18,11 @@ export default function EListSchool({
|
|
|
18
18
|
}: IProps) {
|
|
19
19
|
return (
|
|
20
20
|
<View style={tw`border-b border-slate-200 py-3`}>
|
|
21
|
-
<EText style={tw`font-bold text-slate-800 mb-
|
|
21
|
+
<EText size="base" style={tw`font-bold text-slate-800 mb-1 h-7`} numberOfLines={2}>
|
|
22
22
|
{name}
|
|
23
23
|
</EText>
|
|
24
24
|
<View style={tw`flex-row items-center`}>
|
|
25
|
-
<EText size="sm" style={tw`text-slate-500`}>
|
|
25
|
+
<EText size="sm" style={tw`text-slate-500 mt-0.5`}>
|
|
26
26
|
{code}
|
|
27
27
|
</EText>
|
|
28
28
|
{district ? <><View style={tw`w-1 h-1 bg-slate-600 rounded-full mx-1.5`}></View>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Image } from 'react-native'
|
|
3
|
+
import tw from '../../../lib/tailwind'
|
|
4
|
+
import { View } from 'react-native'
|
|
5
|
+
import EText from './EText'
|
|
6
|
+
import { Colors } from "../utils/Color";
|
|
7
|
+
|
|
8
|
+
interface IProps {
|
|
9
|
+
title: string;
|
|
10
|
+
subtitle: string;
|
|
11
|
+
button?: JSX.Element;
|
|
12
|
+
icon?: JSX.Element;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default function ENotFoundPlaceholder(
|
|
16
|
+
{ title, subtitle, button, icon }: IProps
|
|
17
|
+
) {
|
|
18
|
+
return (
|
|
19
|
+
<View style={tw`items-center px-16 py-2`}>
|
|
20
|
+
<Image
|
|
21
|
+
source={require("../assets/images/icon-placeholder-schedule.png")}
|
|
22
|
+
style={[tw``, { height: 44 }]}
|
|
23
|
+
resizeMode="contain"
|
|
24
|
+
/>
|
|
25
|
+
|
|
26
|
+
<EText
|
|
27
|
+
size="base"
|
|
28
|
+
style={tw`text-center font-bold text-[${Colors["text-primary"]}]`}
|
|
29
|
+
>
|
|
30
|
+
{title}
|
|
31
|
+
</EText>
|
|
32
|
+
<EText
|
|
33
|
+
size="sm"
|
|
34
|
+
style={tw`text-center text-[${Colors["text-secondary"]}]`}
|
|
35
|
+
>
|
|
36
|
+
{subtitle}
|
|
37
|
+
</EText>
|
|
38
|
+
<View style={tw`mt-4`}>
|
|
39
|
+
{button}
|
|
40
|
+
</View>
|
|
41
|
+
</View>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
TouchableOpacity,
|
|
4
|
+
View,
|
|
5
|
+
TouchableOpacityProps,
|
|
6
|
+
Dimensions,
|
|
7
|
+
Image,
|
|
8
|
+
} from "react-native";
|
|
9
|
+
import tw from "../../../lib/tailwind";
|
|
10
|
+
import EText from "./EText";
|
|
11
|
+
import { Colors } from "../utils/Color";
|
|
12
|
+
|
|
13
|
+
const ImageWidth = Dimensions.get("window").width / 2 - 18;
|
|
14
|
+
const ContentWidth = Dimensions.get("window").width - 32;
|
|
15
|
+
const ImageHeight = 140;
|
|
16
|
+
const MediaContainerStyle = "rounded-md overflow-hidden";
|
|
17
|
+
|
|
18
|
+
interface RadioButtonProps extends TouchableOpacityProps {
|
|
19
|
+
text?: string;
|
|
20
|
+
isActive: boolean;
|
|
21
|
+
imageSource?: string;
|
|
22
|
+
optionLabel: string;
|
|
23
|
+
onPress?: () => void;
|
|
24
|
+
}
|
|
25
|
+
const EOption = ({
|
|
26
|
+
isActive,
|
|
27
|
+
text,
|
|
28
|
+
imageSource,
|
|
29
|
+
optionLabel,
|
|
30
|
+
onPress,
|
|
31
|
+
...props
|
|
32
|
+
}: RadioButtonProps) => {
|
|
33
|
+
return (
|
|
34
|
+
<TouchableOpacity
|
|
35
|
+
style={[
|
|
36
|
+
tw`flex flex-row justify-start items-center mt-2 px-4 py-3 border rounded-lg ${
|
|
37
|
+
imageSource ? "flex-col p-0 items-start" : ""
|
|
38
|
+
}`,
|
|
39
|
+
{
|
|
40
|
+
borderColor: isActive ? Colors["secondary-base"] : Colors.border,
|
|
41
|
+
backgroundColor: isActive ? Colors["secondary-light"] : Colors.white,
|
|
42
|
+
width: imageSource ? ImageWidth - 10 : ContentWidth,
|
|
43
|
+
},
|
|
44
|
+
]}
|
|
45
|
+
onPress={() => {
|
|
46
|
+
onPress && onPress();
|
|
47
|
+
}}
|
|
48
|
+
activeOpacity={0.7}
|
|
49
|
+
{...props}
|
|
50
|
+
>
|
|
51
|
+
{imageSource ? (
|
|
52
|
+
<View
|
|
53
|
+
style={[
|
|
54
|
+
tw`${MediaContainerStyle}`,
|
|
55
|
+
{
|
|
56
|
+
height: ImageHeight - 20,
|
|
57
|
+
width: ImageWidth - 12,
|
|
58
|
+
backgroundColor: Colors.white
|
|
59
|
+
},
|
|
60
|
+
]}
|
|
61
|
+
>
|
|
62
|
+
<View
|
|
63
|
+
style={[
|
|
64
|
+
tw`h-8 w-8 bg-slate-300 rounded-full justify-center items-center m-2 absolute z-10`,
|
|
65
|
+
]}
|
|
66
|
+
>
|
|
67
|
+
<EText size={"base"} style={tw`font-normal`}>
|
|
68
|
+
{optionLabel}
|
|
69
|
+
</EText>
|
|
70
|
+
</View>
|
|
71
|
+
<Image
|
|
72
|
+
style={[
|
|
73
|
+
tw`w-full mt-4`,
|
|
74
|
+
{
|
|
75
|
+
opacity: isActive ? 0.5 : 1,
|
|
76
|
+
},
|
|
77
|
+
{height: ImageHeight - 40}
|
|
78
|
+
]}
|
|
79
|
+
source={{uri: imageSource}}
|
|
80
|
+
resizeMode="contain"
|
|
81
|
+
/>
|
|
82
|
+
</View>
|
|
83
|
+
)
|
|
84
|
+
: <></>
|
|
85
|
+
}
|
|
86
|
+
{text ? (
|
|
87
|
+
<EText
|
|
88
|
+
size={"base"}
|
|
89
|
+
style={tw`font-normal ${imageSource ? "py-2 px-4" : ""}`}
|
|
90
|
+
>
|
|
91
|
+
{text}
|
|
92
|
+
</EText>
|
|
93
|
+
) : null}
|
|
94
|
+
</TouchableOpacity>
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export default EOption;
|
|
@@ -1,26 +1,33 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { TouchableOpacity, View } from
|
|
3
|
-
import tw from
|
|
4
|
-
import { Colors } from
|
|
5
|
-
import EText from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { TouchableOpacity, View } from "react-native";
|
|
3
|
+
import tw from "../lib/tailwind";
|
|
4
|
+
import { Colors } from "../utils/Color";
|
|
5
|
+
import EText from "./EText";
|
|
6
6
|
|
|
7
7
|
interface IProps {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
title: string;
|
|
9
|
+
active?: boolean;
|
|
10
|
+
onPress?: () => void;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export default function EPillButton(
|
|
13
|
+
export default function EPillButton({ title, active, onPress }: IProps) {
|
|
14
14
|
return (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
<TouchableOpacity
|
|
16
|
+
style={[
|
|
17
|
+
tw`px-4 py-3 mr-2 border rounded-lg border-slate-300`,
|
|
18
|
+
{
|
|
19
|
+
backgroundColor: active ? Colors["secondary-base"] : "transparent",
|
|
20
|
+
borderColor: active ? Colors["secondary-base"] : Colors["border"],
|
|
21
|
+
},
|
|
22
|
+
]}
|
|
19
23
|
onPress={onPress}
|
|
24
|
+
>
|
|
25
|
+
<EText
|
|
26
|
+
size={"base"}
|
|
27
|
+
style={tw`font-normal ${active ? "text-white" : "text-slate-500"}`}
|
|
20
28
|
>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
</EText>
|
|
29
|
+
{title}
|
|
30
|
+
</EText>
|
|
24
31
|
</TouchableOpacity>
|
|
25
|
-
)
|
|
32
|
+
);
|
|
26
33
|
}
|
package/components/EProfile.tsx
CHANGED
|
@@ -1,43 +1,57 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { View } from
|
|
3
|
-
import tw from
|
|
4
|
-
import { Colors } from
|
|
5
|
-
import Avatar from
|
|
6
|
-
import EText from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import tw from "../lib/tailwind";
|
|
4
|
+
import { Colors } from "../utils/Color";
|
|
5
|
+
import Avatar from "./Avatar";
|
|
6
|
+
import EText from "./EText";
|
|
7
7
|
|
|
8
8
|
interface IProps {
|
|
9
9
|
name: string;
|
|
10
10
|
subjectName?: string;
|
|
11
11
|
border?: boolean;
|
|
12
12
|
children?: JSX.Element;
|
|
13
|
-
|
|
14
|
-
subTitleSize: string;
|
|
15
|
-
|
|
13
|
+
showAvatar?: boolean;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
export default function EProfile({
|
|
16
|
+
export default function EProfile({
|
|
17
|
+
name,
|
|
18
|
+
subjectName,
|
|
19
|
+
border,
|
|
20
|
+
children,
|
|
21
|
+
showAvatar = true
|
|
22
|
+
}: IProps) {
|
|
19
23
|
return (
|
|
20
|
-
<View
|
|
24
|
+
<View
|
|
25
|
+
style={[
|
|
26
|
+
tw`flex-row items-center justify-between py-3 ${border ? "border-b" : ""
|
|
27
|
+
}`,
|
|
28
|
+
{ borderBottomColor: Colors.border },
|
|
29
|
+
]}
|
|
30
|
+
>
|
|
21
31
|
<View style={tw`flex-row items-center`}>
|
|
22
|
-
<Avatar
|
|
32
|
+
{showAvatar ? <Avatar
|
|
23
33
|
size="sm"
|
|
24
34
|
source={""}
|
|
25
|
-
nameFirstLetter={"
|
|
26
|
-
|
|
27
|
-
/>
|
|
35
|
+
nameFirstLetter={name.split(" ")[0].charAt(0)}
|
|
36
|
+
/> : <></>}
|
|
28
37
|
<View style={tw`ml-3`}>
|
|
29
|
-
<EText
|
|
30
|
-
|
|
31
|
-
{
|
|
32
|
-
|
|
38
|
+
<EText
|
|
39
|
+
size={"base"}
|
|
40
|
+
style={[
|
|
41
|
+
tw`font-bold text-slate-800 mb-0 capitalize`,
|
|
42
|
+
{ color: Colors["text-primary"] },
|
|
43
|
+
]}
|
|
44
|
+
>
|
|
45
|
+
{name}
|
|
46
|
+
</EText>
|
|
47
|
+
{subjectName ? (
|
|
48
|
+
<EText size="sm" style={[tw` `, { color: Colors["text-body"] }]}>
|
|
49
|
+
{subjectName}
|
|
50
|
+
</EText>
|
|
51
|
+
) : null}
|
|
33
52
|
</View>
|
|
34
53
|
</View>
|
|
35
|
-
{
|
|
36
|
-
children ? <>
|
|
37
|
-
{children}
|
|
38
|
-
</> : null
|
|
39
|
-
}
|
|
40
|
-
|
|
54
|
+
{children ? <>{children}</> : null}
|
|
41
55
|
</View>
|
|
42
|
-
)
|
|
56
|
+
);
|
|
43
57
|
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Animated, ImageBackground, View } from "react-native";
|
|
2
|
+
// import tw from '../../../lib/tailwind'
|
|
3
|
+
import tw from "../lib/tailwind"
|
|
4
|
+
import EButtonIcon from "./EButtonIcon";
|
|
5
|
+
import EText from "./EText";
|
|
6
|
+
import React, { useCallback, useRef } from "react";
|
|
7
|
+
import Constants from "expo-constants";
|
|
8
|
+
import { SCREEN_HEIGHT } from "@gorhom/bottom-sheet";
|
|
9
|
+
import { useFocusEffect, useNavigation } from "@react-navigation/native";
|
|
10
|
+
import { StatusBar } from "expo-status-bar";
|
|
11
|
+
import ProfileHeader from "./ProfileHeader";
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
interface IProps {
|
|
15
|
+
profileName: string;
|
|
16
|
+
titleText?: string;
|
|
17
|
+
uniqueCode: string;
|
|
18
|
+
body: JSX.Element;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default function EProfileScreenLayout( { profileName, uniqueCode, body, titleText } : IProps) {
|
|
22
|
+
const opacity = useRef(new Animated.Value(0)).current;
|
|
23
|
+
const [headerScrolled, setHeaderScrolled] = React.useState(false);
|
|
24
|
+
const scrollY = useRef(new Animated.Value(0)).current;
|
|
25
|
+
const navigation = useNavigation();
|
|
26
|
+
|
|
27
|
+
React.useEffect(() => {
|
|
28
|
+
Animated.spring(scrollY, {
|
|
29
|
+
toValue: headerScrolled ? 0 : -100,
|
|
30
|
+
speed: 2,
|
|
31
|
+
delay: 1,
|
|
32
|
+
bounciness: 1,
|
|
33
|
+
useNativeDriver: true,
|
|
34
|
+
}).start();
|
|
35
|
+
|
|
36
|
+
Animated.spring(opacity, {
|
|
37
|
+
toValue: headerScrolled ? 0.975 : 0,
|
|
38
|
+
speed: 2,
|
|
39
|
+
delay: 1,
|
|
40
|
+
bounciness: 1,
|
|
41
|
+
useNativeDriver: true,
|
|
42
|
+
}).start();
|
|
43
|
+
}, [headerScrolled]);
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<View style={tw``}>
|
|
49
|
+
<StatusBar
|
|
50
|
+
style={"light"}
|
|
51
|
+
animated
|
|
52
|
+
/>
|
|
53
|
+
<Animated.View
|
|
54
|
+
style={[
|
|
55
|
+
tw`absolute top-0 left-0 right-0 z-10`,
|
|
56
|
+
{
|
|
57
|
+
transform: [{ translateY: scrollY }],
|
|
58
|
+
opacity,
|
|
59
|
+
},
|
|
60
|
+
]}
|
|
61
|
+
>
|
|
62
|
+
<ImageBackground
|
|
63
|
+
style={[tw`flex-1`, {}]}
|
|
64
|
+
source={require("../assets/images/bg-profile.jpg")}
|
|
65
|
+
>
|
|
66
|
+
<View
|
|
67
|
+
style={[
|
|
68
|
+
tw`flex-1 pl-3 pb-3 flex-row items-center `,
|
|
69
|
+
{ paddingTop: Constants.statusBarHeight + 4 },
|
|
70
|
+
]}
|
|
71
|
+
>
|
|
72
|
+
<EButtonIcon
|
|
73
|
+
iconColor={"white"}
|
|
74
|
+
size={20}
|
|
75
|
+
onPress={() => navigation.goBack()}
|
|
76
|
+
/>
|
|
77
|
+
<EText size="lg" style={tw`text-white font-bold ml-2`}>
|
|
78
|
+
Profile
|
|
79
|
+
</EText>
|
|
80
|
+
</View>
|
|
81
|
+
</ImageBackground>
|
|
82
|
+
</Animated.View>
|
|
83
|
+
|
|
84
|
+
<Animated.ScrollView
|
|
85
|
+
onScroll={(event) => {
|
|
86
|
+
const scrolling = event.nativeEvent.contentOffset.y;
|
|
87
|
+
scrolling > 40 ? setHeaderScrolled(true) : setHeaderScrolled(false);
|
|
88
|
+
}}
|
|
89
|
+
style={[tw`flex-1 bg-white`, { minHeight: SCREEN_HEIGHT, paddingBottom: 100 }]}
|
|
90
|
+
scrollEventThrottle={16}
|
|
91
|
+
showsVerticalScrollIndicator={false}
|
|
92
|
+
decelerationRate={"fast"}
|
|
93
|
+
contentContainerStyle={{
|
|
94
|
+
paddingBottom: 100
|
|
95
|
+
}}
|
|
96
|
+
>
|
|
97
|
+
|
|
98
|
+
<ProfileHeader
|
|
99
|
+
name={profileName?.trim() || ""}
|
|
100
|
+
title={uniqueCode || ""}
|
|
101
|
+
titleText={titleText ? titleText : "Unique Code"}
|
|
102
|
+
/>
|
|
103
|
+
|
|
104
|
+
<View style={tw`px-4 mt-8 flex-1`}>
|
|
105
|
+
{body}
|
|
106
|
+
</View>
|
|
107
|
+
|
|
108
|
+
</Animated.ScrollView>
|
|
109
|
+
</View>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react'
|
|
2
|
+
import { Animated, StyleSheet, View } from 'react-native';
|
|
3
|
+
import tw from "fln-espranza/lib/tailwind";
|
|
4
|
+
import { Colors } from "fln-espranza/utils/Color";
|
|
5
|
+
|
|
6
|
+
interface IProps {
|
|
7
|
+
progress: number;
|
|
8
|
+
type: "stepper" | "bar";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function EProgressBar({ progress, type }: IProps) {
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const barWidth = useRef(new Animated.Value(0)).current;
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
Animated.spring(barWidth, {
|
|
18
|
+
toValue: progress,
|
|
19
|
+
bounciness: 0,
|
|
20
|
+
speed: 7,
|
|
21
|
+
useNativeDriver: false,
|
|
22
|
+
}).start();
|
|
23
|
+
}, [progress]);
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
{type === "stepper" ? <View style={[tw`h-2 w-14 bg-slate-200 overflow-hidden mr-2`, {
|
|
27
|
+
borderRadius: 40,
|
|
28
|
+
}]}>
|
|
29
|
+
<Animated.View
|
|
30
|
+
style={[StyleSheet.absoluteFill, { backgroundColor: Colors['primary-base'], width: barWidth }]}
|
|
31
|
+
|
|
32
|
+
/>
|
|
33
|
+
</View>
|
|
34
|
+
:
|
|
35
|
+
|
|
36
|
+
<View style={[tw`h-1 w-full bg-white/10 overflow-hidden mt-1`, {
|
|
37
|
+
borderRadius: 40,
|
|
38
|
+
}]}>
|
|
39
|
+
<View
|
|
40
|
+
style={[tw`h-1 w-[${progress}%] bg-[${Colors['primary-base']}]`]}
|
|
41
|
+
|
|
42
|
+
/>
|
|
43
|
+
</View>
|
|
44
|
+
}
|
|
45
|
+
</>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import tw from '../lib/tailwind';
|
|
3
|
+
import { Colors } from '../utils/Color';
|
|
4
|
+
import EText from './EText';
|
|
5
|
+
// import { EText } from '../../../components'
|
|
6
|
+
|
|
7
|
+
interface IProps{
|
|
8
|
+
label: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function EQuestionSerialNumberLabel( { label } : IProps) {
|
|
12
|
+
return (
|
|
13
|
+
<EText size={"sm"} style={[tw`font-extrabold`, {color: Colors['primary-base']}]}>
|
|
14
|
+
{label}
|
|
15
|
+
</EText>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import tw from '../lib/tailwind';
|
|
3
|
+
import EText from './EText';
|
|
4
|
+
interface IProps{
|
|
5
|
+
question: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default function EQuestionText( { question } : IProps) {
|
|
9
|
+
return (
|
|
10
|
+
<EText size={"base"} style={ tw`font-medium mt-1`}>
|
|
11
|
+
{question}
|
|
12
|
+
</EText>
|
|
13
|
+
)
|
|
14
|
+
}
|