<commit_before>import { Button, Card, Divider, Input, Layout, Text } from '@ui-kitten/components';
import { Formik } from 'formik';
import ky from 'ky';
import React from 'react';
import { Alert, ScrollView, StyleSheet, View } from 'react-native';
import { useMutation, useQuery, useQueryClient } from 'react-query';
import * as Sentry from 'sentry-expo';
import * as yup from 'yup';
import 'yup-phone';
import useAuth from '../auth/context';
import MyPhoneInput from '../components/MyPhoneInput';
import Spinner from '../components/Spinner';
import ValueContainer from '../components/ValueContainer';
import config from '../services/config';
import { PADDING } from '../services/styles';
import { booleanToYesNo, dateToString } from '../services/utilities';

export default function ProfileScreen() {
  const { getBearerToken } = useAuth();

  const getProfileData = async () => {
    const headers = {
      Authorization: await getBearerToken(),
    };
    let responseJson;
    try {
      responseJson = await ky.get(`${config.API}/user/profile`, { headers }).json();

      return responseJson.profile;
    } catch (error) {
      Sentry.Native.captureException(error);
      throw error;
    }
  };
  const { data, isLoading, isError, error } = useQuery(config.QUERY_KEYS.profile, getProfileData);

  const updateProfileData = async (newData) => {
    const headers = {
      Authorization: await getBearerToken(),
    };

    try {
      await ky.post(`${config.API}/user/profile/update`, { headers, json: newData }).json();
    } catch (error) {
      Sentry.Native.captureException(error);
      throw error;
    }
  };

  const queryClient = useQueryClient();
  const mutation = useMutation(updateProfileData, {
    onSuccess: () => {
      Alert.alert('Success', 'Profile updated successfully!');

      queryClient.invalidateQueries(config.QUERY_KEYS.profile);
    },
    onError: (error) => {
      Sentry.Native.captureException(error);

      Alert.alert('Error', 'Error updating profile!');
    },
  });

  const shape = {
    phone: yup.string().phone('US').required(),
  };
  if (data?.organization) {
    shape.organization = yup.string().required();
  }
  const schema = yup.object().shape(shape);

  return (
    <Layout style={styles.container}>
      <ScrollView style={styles.container}>
        {isError ? (
          <Card status="danger" style={styles.errorCard}>
            <Text>There was an error retrieving your profile from the server!</Text>
            <Text>{error?.message}</Text>
          </Card>
        ) : null}
        {data ? (
          <>
            <View style={{ padding: PADDING }}>
              <Input
                label="Name (from sign-in provider)"
                value={`${data.first_name} ${data.last_name}`}
                disabled
                style={styles.padded}
              />
              <Input label="Email (from sign-in provider)" value={`${data.email}`} disabled style={styles.padded} />
              <Formik
                initialValues={{
                  phone: data.phone,
                  organization: data.organization,
                }}
                onSubmit={(values) => {
                  mutation.mutate(values);
                }}
                validationSchema={schema}
              >
                {({ values, handleChange, handleBlur, handleSubmit, dirty, errors, isValid }) => (
                  <>
                    <MyPhoneInput
                      accessibilityRole="text"
                      accessibilityLabel="phone"
                      keyboardType="phone-pad"
                      textContentType="telephoneNumber"
                      label="Phone"
                      value={values.phone}
                      style={styles.padded}
                      onChange={handleChange('phone')}
                      onBlur={handleBlur('phone')}
                      status={errors.phone ? 'danger' : null}
                    />
                    {data.organization !== null ? (
                      <Input
                        accessibilityRole="text"
                        accessibilityLabel="organization"
                        label="Organization"
                        value={values.organization}<commit_msg>fix(front): fix bug preventing multiple changes to profile data<commit_after>import { Button, Card, Divider, Input, Layout, Text } from '@ui-kitten/components';
import { Formik } from 'formik';
import ky from 'ky';
import React, { useRef } from 'react';
import { Alert, ScrollView, StyleSheet, View } from 'react-native';
import { useMutation, useQuery, useQueryClient } from 'react-query';
import * as Sentry from 'sentry-expo';
import * as yup from 'yup';
import 'yup-phone';
import useAuth from '../auth/context';
import MyPhoneInput from '../components/MyPhoneInput';
import Spinner from '../components/Spinner';
import ValueContainer from '../components/ValueContainer';
import config from '../services/config';
import { PADDING } from '../services/styles';
import { booleanToYesNo, dateToString } from '../services/utilities';

export default function ProfileScreen() {
  const { getBearerToken } = useAuth();

  const getProfileData = async () => {
    const headers = {
      Authorization: await getBearerToken(),
    };
    let responseJson;
    try {
      responseJson = await ky.get(`${config.API}/user/profile`, { headers }).json();

      return responseJson.profile;
    } catch (error) {
      Sentry.Native.captureException(error);
      throw error;
    }
  };
  const { data, isLoading, isError, error } = useQuery(config.QUERY_KEYS.profile, getProfileData);

  const updateProfileData = async (newData) => {
    const headers = {
      Authorization: await getBearerToken(),
    };

    try {
      await ky.post(`${config.API}/user/profile/update`, { headers, json: newData }).json();
    } catch (error) {
      Sentry.Native.captureException(error);
      throw error;
    }
  };

  const formikRef = useRef();
  const queryClient = useQueryClient();
  const mutation = useMutation(updateProfileData, {
    onSuccess: () => {
      Alert.alert('Success', 'Profile updated successfully!');

      queryClient.invalidateQueries(config.QUERY_KEYS.profile);

      formikRef.current.resetForm({
        values: formikRef.current.values,
      });
    },
    onError: (error) => {
      Sentry.Native.captureException(error);

      Alert.alert('Error', 'Error updating profile!');
    },
  });

  const shape = {
    phone: yup.string().phone('US').required(),
  };
  if (data?.organization) {
    shape.organization = yup.string().required();
  }
  const schema = yup.object().shape(shape);

  return (
    <Layout style={styles.container}>
      <ScrollView style={styles.container}>
        {isError ? (
          <Card status="danger" style={styles.errorCard}>
            <Text>There was an error retrieving your profile from the server!</Text>
            <Text>{error?.message}</Text>
          </Card>
        ) : null}
        {data ? (
          <>
            <View style={{ padding: PADDING }}>
              <Input
                label="Name (from sign-in provider)"
                value={`${data.first_name} ${data.last_name}`}
                disabled
                style={styles.padded}
              />
              <Input label="Email (from sign-in provider)" value={`${data.email}`} disabled style={styles.padded} />
              <Formik
                innerRef={formikRef}
                initialValues={{
                  phone: data.phone,
                  organization: data.organization,
                }}
                onSubmit={(values) => {
                  mutation.mutate(values);
                }}
                validationSchema={schema}
              >
                {({ values, handleChange, handleBlur, handleSubmit, dirty, errors, isValid }) => (
                  <>
                    <MyPhoneInput
                      accessibilityRole="text"
                      accessibilityLabel="phone"
                      keyboardType="phone-pad"
                      textContentType="telephoneNumber"
                      label="Phone"
                      value={values.phone}
                      style={styles.padded}
                      onChange={handleChange('phone')}
                      onBlur={handleBlur('phone')}
                      status={errors.phone ? 'danger' : null}
                    />
                    {data.organization !== null ? (
                      <Input
                        accessibilityRole="text"
                        accessibilityLabel="organization"
                        label="Organization"
                        value={values.organization}
{'fraction_non_alphanumeric': 0.1290692342961944, 'fraction_numerical': 0.0, 'mean_word_length': 2.0169432918395573, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6618693', 'n_tokens_mistral': 2340, 'n_tokens_neox': 2224, 'n_words': 501}