casper's Profile Image

Full Stack Web/Mobile Developer

Dec, 13, 2024

React Native Expo Tutorial #4 | Ecommerce App - Profile Screen

we created profile component and edited a few related component and screens.

React Native Expo Tutorial #4 | Ecommerce App - Profile Screen Image

You can also watch the YouTube video:

React Native Expo Tutorial #4 | Ecommerce App - Profile Screen

Installing Gluestack UI Components

npx gluestack-ui add alert alert-dialog avatar divider link

Creating LogoutAlertDialog Component

Create LogoutAlertDialog.tsx in components folder:

import { X } from "lucide-react-native";
import {
  AlertDialog,
  AlertDialogBackdrop,
  AlertDialogBody,
  AlertDialogCloseButton,
  AlertDialogContent,
  AlertDialogFooter,
  AlertDialogHeader,
} from "./ui/alert-dialog";
import { Button, ButtonText } from "./ui/button";
import { Heading } from "./ui/heading";
import { Icon } from "./ui/icon";
import { Text } from "./ui/text";

const LogoutAlertDialog = ({
  openLogoutAlertDialog,
  setOpenLogoutAlertDialog,
  setCurrentComponent,
}: any) => {
  const handleClose = () => {
    setOpenLogoutAlertDialog(false);
  };

  return (
    <AlertDialog isOpen={openLogoutAlertDialog} onClose={handleClose}>
      <AlertDialogBackdrop />
      <AlertDialogContent className="p-4">
        <AlertDialogHeader>
          <Heading>Logout</Heading>
          <AlertDialogCloseButton>
            <Icon as={X} />
          </AlertDialogCloseButton>
        </AlertDialogHeader>
        <AlertDialogBody className="" contentContainerClassName="">
          <Text className="mb-6">Are you sure, you want to logout?</Text>
        </AlertDialogBody>
        <AlertDialogFooter>
          <Button variant="outline" action="secondary" onPress={handleClose}>
            <ButtonText>Cancel</ButtonText>
          </Button>
          <Button
            action="negative"
            onPress={() => setCurrentComponent("SignIn")}
          >
            <ButtonText className="text-white">Logout</ButtonText>
          </Button>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
};

export default LogoutAlertDialog;

Creating Profile Component

Create Profile.tsx in components folder:

import {
  Blinds,
  ChevronRight,
  HeadsetIcon,
  MessageCircleQuestionIcon,
  Settings,
  Tablets,
  User,
} from "lucide-react-native";
import React, { useState } from "react";
import { Pressable, ScrollView } from "react-native";
import LogoutAlertDialog from "./LogoutAlertDialog";
import { Avatar, AvatarFallbackText, AvatarImage } from "./ui/avatar";
import { Button, ButtonText } from "./ui/button";
import { Divider } from "./ui/divider";
import { Heading } from "./ui/heading";
import { HStack } from "./ui/hstack";
import { Icon } from "./ui/icon";
import { Link, LinkText } from "./ui/link";
import { Text } from "./ui/text";
import { VStack } from "./ui/vstack";

interface IProfile {
  setCurrentComponent: React.Dispatch<React.SetStateAction<string>>;
}

const Profile: React.FC<IProfile> = ({ setCurrentComponent }) => {
  const [openLogoutAlertDialog, setOpenLogoutAlertDialog] = useState(false);

  return (
    <ScrollView>
      <VStack className="px-5 py-4 flex-1" space="lg">
        <Heading className="mb-1">Profile</Heading>
        <HStack className="justify-between items-center">
          <HStack space="md">
            <Avatar className="bg-primary-500">
              <AvatarFallbackText>Henry Stan</AvatarFallbackText>
              <AvatarImage
                source={{
                  uri: "https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8dXNlcnxlbnwwfHwwfHw%3D&auto=format&fit=crop&w=800&q=60",
                }}
              />
            </Avatar>
            <VStack>
              <Text>Henry Stan</Text>
              <Link>
                <LinkText
                  size="sm"
                  className="text-typography-500 no-underline hover:text-typography-500 active:text-typography-500"
                >
                  Show Profile
                </LinkText>
              </Link>
            </VStack>
          </HStack>
          <Pressable>
            <Icon as={ChevronRight} />
          </Pressable>
        </HStack>
        <Divider className="my-2" />
        <VStack space="lg">
          <HStack className="justify-between">
            <HStack space="md">
              <Icon as={User} />
              <Text>Personal Info</Text>
            </HStack>
            <Pressable>
              <Icon as={ChevronRight} />
            </Pressable>
          </HStack>
          <HStack className="justify-between">
            <HStack space="md">
              <Icon as={Settings} />
              <Text>Account</Text>
            </HStack>
            <Pressable>
              <Icon as={ChevronRight} />
            </Pressable>
          </HStack>
        </VStack>

        <Divider className="my-2" />
        <VStack space="lg">
          <Heading className="mb-1">Privacy Policy</Heading>
          <HStack className="justify-between">
            <HStack space="md">
              <Icon as={Blinds} />
              <Text>Terms and Conditions</Text>
            </HStack>
            <Pressable>
              <Icon as={ChevronRight} />
            </Pressable>
          </HStack>
          <HStack className="justify-between">
            <HStack space="md">
              <Icon as={Tablets} />
              <Text>Terms of Services</Text>
            </HStack>
            <Pressable>
              <Icon as={ChevronRight} />
            </Pressable>
          </HStack>
        </VStack>
        <Divider className="my-2" />
        <VStack space="lg">
          <Heading className="mb-1">Support</Heading>
          <HStack className="justify-between">
            <HStack space="md">
              <Icon as={MessageCircleQuestionIcon} />
              <Text>Get Help</Text>
            </HStack>
            <Pressable>
              <Icon as={ChevronRight} />
            </Pressable>
          </HStack>
          <HStack className="justify-between">
            <HStack space="md">
              <Icon as={HeadsetIcon} />
              <Text>Contact Support</Text>
            </HStack>
            <Pressable>
              <Icon as={ChevronRight} />
            </Pressable>
          </HStack>
        </VStack>
        <Divider className="my-2" />
        <Button
          action="secondary"
          variant="outline"
          onPress={() => {
            setOpenLogoutAlertDialog(true);
          }}
        >
          <ButtonText>Logout</ButtonText>
        </Button>
      </VStack>

      <LogoutAlertDialog
        setOpenLogoutAlertDialog={setOpenLogoutAlertDialog}
        openLogoutAlertDialog={openLogoutAlertDialog}
        setCurrentComponent={setCurrentComponent}
      />
    </ScrollView>
  );
};

export default Profile;

Editing OTP Component

Edit OTP.tsx in components folder:

import { OtpInput } from "react-native-otp-entry";
import { Box } from "./ui/box";
import { Button, ButtonText } from "./ui/button";
import { Heading } from "./ui/heading";
import { VStack } from "./ui/vstack";

interface IOTP {
  setCurrentComponent: React.Dispatch<React.SetStateAction<string>>;
}

const OTP: React.FC<IOTP> = ({ setCurrentComponent }) => {
  return (
    <Box className="border-outline-300 border rounded-lg">
      <Box className="p-8">
        <Heading>Enter the code we've sent your email address.</Heading>

        <VStack className="mt-4" space="lg">
          <OtpInput
            focusColor="blue"
            numberOfDigits={6}
            onTextChange={(text) => console.log(text)}
          />

          <Button
            className="bg-blue-500"
            onPress={() => setCurrentComponent("Profile")}
          >
            <ButtonText>Continue</ButtonText>
          </Button>
        </VStack>
      </Box>
    </Box>
  );
};

export default OTP;

Editing User Screen

Edit user.tsx in app/(tabs)/ folder:

import ForgotPassword from "@/components/ForgotPassword";
import OTP from "@/components/OTP";
import Profile from "@/components/Profile";
import SignIn from "@/components/SignIn";
import SignUp from "@/components/SignUp";
import { Box } from "@/components/ui/box";
import { useState } from "react";

const UserScreen = () => {
  const [currentComponent, setCurrentComponent] = useState("Profile");

  return (
    <Box className="flex-1 pt-8 bg-white">
      {currentComponent === "SignIn" ? (
        <SignIn setCurrentComponent={setCurrentComponent} />
      ) : undefined}
      {currentComponent === "SignUp" ? (
        <SignUp setCurrentComponent={setCurrentComponent} />
      ) : undefined}
      {currentComponent === "ForgotPassword" ? (
        <ForgotPassword setCurrentComponent={setCurrentComponent} />
      ) : undefined}
      {currentComponent === "OTP" ? (
        <OTP setCurrentComponent={setCurrentComponent} />
      ) : undefined}
      {currentComponent === "Profile" ? (
        <Profile setCurrentComponent={setCurrentComponent} />
      ) : undefined}
    </Box>
  );
};

export default UserScreen;

That's it for this tutorial, we created profile component and edited a few related component and screens.

Next tutorial we'll start listing products in our home screen.

0
0

Comments (0)