feat: add user profile settings tab
This commit is contained in:
		@@ -3,11 +3,20 @@ import styled from 'styled-components/macro';
 | 
				
			|||||||
import GlobalTopNavbar from 'App/TopNavbar';
 | 
					import GlobalTopNavbar from 'App/TopNavbar';
 | 
				
			||||||
import { getAccessToken } from 'shared/utils/accessToken';
 | 
					import { getAccessToken } from 'shared/utils/accessToken';
 | 
				
			||||||
import Settings from 'shared/components/Settings';
 | 
					import Settings from 'shared/components/Settings';
 | 
				
			||||||
import { useMeQuery, useClearProfileAvatarMutation, useUpdateUserPasswordMutation } from 'shared/generated/graphql';
 | 
					import {
 | 
				
			||||||
 | 
					  useMeQuery,
 | 
				
			||||||
 | 
					  useClearProfileAvatarMutation,
 | 
				
			||||||
 | 
					  useUpdateUserPasswordMutation,
 | 
				
			||||||
 | 
					  useUpdateUserInfoMutation,
 | 
				
			||||||
 | 
					  MeQuery,
 | 
				
			||||||
 | 
					  MeDocument,
 | 
				
			||||||
 | 
					} from 'shared/generated/graphql';
 | 
				
			||||||
import axios from 'axios';
 | 
					import axios from 'axios';
 | 
				
			||||||
import { useCurrentUser } from 'App/context';
 | 
					import { useCurrentUser } from 'App/context';
 | 
				
			||||||
import NOOP from 'shared/utils/noop';
 | 
					import NOOP from 'shared/utils/noop';
 | 
				
			||||||
import { toast } from 'react-toastify';
 | 
					import { toast } from 'react-toastify';
 | 
				
			||||||
 | 
					import updateApolloCache from 'shared/utils/cache';
 | 
				
			||||||
 | 
					import produce from 'immer';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MainContent = styled.div`
 | 
					const MainContent = styled.div`
 | 
				
			||||||
  padding: 0 0 50px 80px;
 | 
					  padding: 0 0 50px 80px;
 | 
				
			||||||
@@ -19,6 +28,7 @@ const Projects = () => {
 | 
				
			|||||||
  const $fileUpload = useRef<HTMLInputElement>(null);
 | 
					  const $fileUpload = useRef<HTMLInputElement>(null);
 | 
				
			||||||
  const [clearProfileAvatar] = useClearProfileAvatarMutation();
 | 
					  const [clearProfileAvatar] = useClearProfileAvatarMutation();
 | 
				
			||||||
  const { user } = useCurrentUser();
 | 
					  const { user } = useCurrentUser();
 | 
				
			||||||
 | 
					  const [updateUserInfo] = useUpdateUserInfoMutation();
 | 
				
			||||||
  const [updateUserPassword] = useUpdateUserPasswordMutation();
 | 
					  const [updateUserPassword] = useUpdateUserPasswordMutation();
 | 
				
			||||||
  const { loading, data, refetch } = useMeQuery();
 | 
					  const { loading, data, refetch } = useMeQuery();
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
@@ -69,6 +79,13 @@ const Projects = () => {
 | 
				
			|||||||
            toast('Password was changed!');
 | 
					            toast('Password was changed!');
 | 
				
			||||||
            done();
 | 
					            done();
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
 | 
					          onChangeUserInfo={(d, done) => {
 | 
				
			||||||
 | 
					            updateUserInfo({
 | 
				
			||||||
 | 
					              variables: { name: d.full_name, bio: d.bio, email: d.email, initials: d.initials },
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            toast('User info was saved!');
 | 
				
			||||||
 | 
					            done();
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
          onProfileAvatarRemove={() => {
 | 
					          onProfileAvatarRemove={() => {
 | 
				
			||||||
            clearProfileAvatar();
 | 
					            clearProfileAvatar();
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -557,6 +557,7 @@ const Admin: React.FC<AdminProps> = ({
 | 
				
			|||||||
        <TabNavContent>
 | 
					        <TabNavContent>
 | 
				
			||||||
          {items.map((item, idx) => (
 | 
					          {items.map((item, idx) => (
 | 
				
			||||||
            <NavItem
 | 
					            <NavItem
 | 
				
			||||||
 | 
					              key={item.name}
 | 
				
			||||||
              onClick={(tab, top) => {
 | 
					              onClick={(tab, top) => {
 | 
				
			||||||
                if ($tabNav && $tabNav.current) {
 | 
					                if ($tabNav && $tabNav.current) {
 | 
				
			||||||
                  const pos = $tabNav.current.getBoundingClientRect();
 | 
					                  const pos = $tabNav.current.getBoundingClientRect();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,6 +78,7 @@ const Icon = styled.div`
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type InputProps = {
 | 
					type InputProps = {
 | 
				
			||||||
  variant?: 'normal' | 'alternate';
 | 
					  variant?: 'normal' | 'alternate';
 | 
				
			||||||
 | 
					  disabled?: boolean;
 | 
				
			||||||
  label?: string;
 | 
					  label?: string;
 | 
				
			||||||
  width?: string;
 | 
					  width?: string;
 | 
				
			||||||
  floatingLabel?: boolean;
 | 
					  floatingLabel?: boolean;
 | 
				
			||||||
@@ -116,6 +117,7 @@ function useCombinedRefs(...refs: any) {
 | 
				
			|||||||
const Input = React.forwardRef(
 | 
					const Input = React.forwardRef(
 | 
				
			||||||
  (
 | 
					  (
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      disabled = false,
 | 
				
			||||||
      width = 'auto',
 | 
					      width = 'auto',
 | 
				
			||||||
      variant = 'normal',
 | 
					      variant = 'normal',
 | 
				
			||||||
      type = 'text',
 | 
					      type = 'text',
 | 
				
			||||||
@@ -160,6 +162,7 @@ const Input = React.forwardRef(
 | 
				
			|||||||
          onChange={e => {
 | 
					          onChange={e => {
 | 
				
			||||||
            setHasValue((e.currentTarget.value !== '' || floatingLabel) ?? false);
 | 
					            setHasValue((e.currentTarget.value !== '' || floatingLabel) ?? false);
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
 | 
					          disabled={disabled}
 | 
				
			||||||
          hasValue={hasValue}
 | 
					          hasValue={hasValue}
 | 
				
			||||||
          ref={combinedRef}
 | 
					          ref={combinedRef}
 | 
				
			||||||
          id={id}
 | 
					          id={id}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,7 @@ export const Default = () => {
 | 
				
			|||||||
      <BaseStyles />
 | 
					      <BaseStyles />
 | 
				
			||||||
      <Settings
 | 
					      <Settings
 | 
				
			||||||
        profile={profile}
 | 
					        profile={profile}
 | 
				
			||||||
 | 
					        onChangeUserInfo={action('change user info')}
 | 
				
			||||||
        onResetPassword={action('reset password')}
 | 
					        onResetPassword={action('reset password')}
 | 
				
			||||||
        onProfileAvatarRemove={action('remove')}
 | 
					        onProfileAvatarRemove={action('remove')}
 | 
				
			||||||
        onProfileAvatarChange={action('profile avatar change')}
 | 
					        onProfileAvatarChange={action('profile avatar change')}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,11 @@ const PasswordInput = styled(Input)`
 | 
				
			|||||||
  margin-bottom: 0;
 | 
					  margin-bottom: 0;
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const UserInfoInput = styled(Input)`
 | 
				
			||||||
 | 
					  margin-top: 30px;
 | 
				
			||||||
 | 
					  margin-bottom: 0;
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const FormError = styled.span`
 | 
					const FormError = styled.span`
 | 
				
			||||||
  font-size: 12px;
 | 
					  font-size: 12px;
 | 
				
			||||||
  color: rgba(${props => props.theme.colors.warning});
 | 
					  color: rgba(${props => props.theme.colors.warning});
 | 
				
			||||||
@@ -240,6 +245,7 @@ const SaveButton = styled(Button)`
 | 
				
			|||||||
type SettingsProps = {
 | 
					type SettingsProps = {
 | 
				
			||||||
  onProfileAvatarChange: () => void;
 | 
					  onProfileAvatarChange: () => void;
 | 
				
			||||||
  onProfileAvatarRemove: () => void;
 | 
					  onProfileAvatarRemove: () => void;
 | 
				
			||||||
 | 
					  onChangeUserInfo: (data: UserInfoData, done: () => void) => void;
 | 
				
			||||||
  onResetPassword: (password: string, done: () => void) => void;
 | 
					  onResetPassword: (password: string, done: () => void) => void;
 | 
				
			||||||
  profile: TaskUser;
 | 
					  profile: TaskUser;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -300,9 +306,93 @@ const ResetPasswordTab: React.FC<ResetPasswordTabProps> = ({ onResetPassword })
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UserInfoData = {
 | 
				
			||||||
 | 
					  full_name: string;
 | 
				
			||||||
 | 
					  bio: string;
 | 
				
			||||||
 | 
					  initials: string;
 | 
				
			||||||
 | 
					  email: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					type UserInfoTabProps = {
 | 
				
			||||||
 | 
					  profile: TaskUser;
 | 
				
			||||||
 | 
					  onProfileAvatarChange: () => void;
 | 
				
			||||||
 | 
					  onProfileAvatarRemove: () => void;
 | 
				
			||||||
 | 
					  onChangeUserInfo: (data: UserInfoData, done: () => void) => void;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const EMAIL_PATTERN = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/i;
 | 
				
			||||||
 | 
					const INITIALS_PATTERN = /^[a-zA-Z]{2,3}$/i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const UserInfoTab: React.FC<UserInfoTabProps> = ({
 | 
				
			||||||
 | 
					  profile,
 | 
				
			||||||
 | 
					  onProfileAvatarRemove,
 | 
				
			||||||
 | 
					  onProfileAvatarChange,
 | 
				
			||||||
 | 
					  onChangeUserInfo,
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const [active, setActive] = useState(true);
 | 
				
			||||||
 | 
					  const { register, handleSubmit, errors } = useForm<UserInfoData>();
 | 
				
			||||||
 | 
					  const done = () => {
 | 
				
			||||||
 | 
					    setActive(true);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      <AvatarSettings
 | 
				
			||||||
 | 
					        onProfileAvatarRemove={onProfileAvatarRemove}
 | 
				
			||||||
 | 
					        onProfileAvatarChange={onProfileAvatarChange}
 | 
				
			||||||
 | 
					        profile={profile.profileIcon}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					      <form
 | 
				
			||||||
 | 
					        onSubmit={handleSubmit(data => {
 | 
				
			||||||
 | 
					          setActive(false);
 | 
				
			||||||
 | 
					          onChangeUserInfo(data, done);
 | 
				
			||||||
 | 
					        })}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <UserInfoInput
 | 
				
			||||||
 | 
					          ref={register({ required: 'Full name is required' })}
 | 
				
			||||||
 | 
					          name="full_name"
 | 
				
			||||||
 | 
					          defaultValue={profile.fullName}
 | 
				
			||||||
 | 
					          width="100%"
 | 
				
			||||||
 | 
					          label="Name"
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        {errors.full_name && <FormError>{errors.full_name.message}</FormError>}
 | 
				
			||||||
 | 
					        <UserInfoInput
 | 
				
			||||||
 | 
					          defaultValue={profile.profileIcon && profile.profileIcon.initials ? profile.profileIcon.initials : ''}
 | 
				
			||||||
 | 
					          ref={register({
 | 
				
			||||||
 | 
					            required: 'Initials is required',
 | 
				
			||||||
 | 
					            pattern: { value: INITIALS_PATTERN, message: 'Intials must be between two to four characters' },
 | 
				
			||||||
 | 
					          })}
 | 
				
			||||||
 | 
					          name="initials"
 | 
				
			||||||
 | 
					          width="100%"
 | 
				
			||||||
 | 
					          label="Initials "
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        {errors.initials && <FormError>{errors.initials.message}</FormError>}
 | 
				
			||||||
 | 
					        <UserInfoInput disabled defaultValue={profile.username ?? ''} width="100%" label="Username " />
 | 
				
			||||||
 | 
					        <UserInfoInput
 | 
				
			||||||
 | 
					          width="100%"
 | 
				
			||||||
 | 
					          name="email"
 | 
				
			||||||
 | 
					          ref={register({
 | 
				
			||||||
 | 
					            required: 'Email is required',
 | 
				
			||||||
 | 
					            pattern: { value: EMAIL_PATTERN, message: 'Must be a valid email' },
 | 
				
			||||||
 | 
					          })}
 | 
				
			||||||
 | 
					          defaultValue={profile.email ?? ''}
 | 
				
			||||||
 | 
					          label="Email"
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        {errors.email && <FormError>{errors.email.message}</FormError>}
 | 
				
			||||||
 | 
					        <UserInfoInput width="100%" name="bio" ref={register()} defaultValue={profile.bio ?? ''} label="Bio" />
 | 
				
			||||||
 | 
					        {errors.bio && <FormError>{errors.bio.message}</FormError>}
 | 
				
			||||||
 | 
					        <SettingActions>
 | 
				
			||||||
 | 
					          <SaveButton disabled={!active} type="submit">
 | 
				
			||||||
 | 
					            Save Change
 | 
				
			||||||
 | 
					          </SaveButton>
 | 
				
			||||||
 | 
					        </SettingActions>
 | 
				
			||||||
 | 
					      </form>
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Settings: React.FC<SettingsProps> = ({
 | 
					const Settings: React.FC<SettingsProps> = ({
 | 
				
			||||||
  onProfileAvatarRemove,
 | 
					  onProfileAvatarRemove,
 | 
				
			||||||
  onProfileAvatarChange,
 | 
					  onProfileAvatarChange,
 | 
				
			||||||
 | 
					  onChangeUserInfo,
 | 
				
			||||||
  onResetPassword,
 | 
					  onResetPassword,
 | 
				
			||||||
  profile,
 | 
					  profile,
 | 
				
			||||||
}) => {
 | 
					}) => {
 | 
				
			||||||
@@ -315,6 +405,7 @@ const Settings: React.FC<SettingsProps> = ({
 | 
				
			|||||||
        <TabNavContent>
 | 
					        <TabNavContent>
 | 
				
			||||||
          {items.map((item, idx) => (
 | 
					          {items.map((item, idx) => (
 | 
				
			||||||
            <NavItem
 | 
					            <NavItem
 | 
				
			||||||
 | 
					              key={item.name}
 | 
				
			||||||
              onClick={(tab, top) => {
 | 
					              onClick={(tab, top) => {
 | 
				
			||||||
                if ($tabNav && $tabNav.current) {
 | 
					                if ($tabNav && $tabNav.current) {
 | 
				
			||||||
                  const pos = $tabNav.current.getBoundingClientRect();
 | 
					                  const pos = $tabNav.current.getBoundingClientRect();
 | 
				
			||||||
@@ -332,23 +423,12 @@ const Settings: React.FC<SettingsProps> = ({
 | 
				
			|||||||
      </TabNav>
 | 
					      </TabNav>
 | 
				
			||||||
      <TabContentWrapper>
 | 
					      <TabContentWrapper>
 | 
				
			||||||
        <Tab tab={0} currentTab={currentTab}>
 | 
					        <Tab tab={0} currentTab={currentTab}>
 | 
				
			||||||
          <AvatarSettings
 | 
					          <UserInfoTab
 | 
				
			||||||
            onProfileAvatarRemove={onProfileAvatarRemove}
 | 
					 | 
				
			||||||
            onProfileAvatarChange={onProfileAvatarChange}
 | 
					            onProfileAvatarChange={onProfileAvatarChange}
 | 
				
			||||||
            profile={profile.profileIcon}
 | 
					            onProfileAvatarRemove={onProfileAvatarRemove}
 | 
				
			||||||
 | 
					            profile={profile}
 | 
				
			||||||
 | 
					            onChangeUserInfo={onChangeUserInfo}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
          <Input defaultValue={profile.fullName} width="100%" label="Name" />
 | 
					 | 
				
			||||||
          <Input
 | 
					 | 
				
			||||||
            defaultValue={profile.profileIcon && profile.profileIcon.initials ? profile.profileIcon.initials : ''}
 | 
					 | 
				
			||||||
            width="100%"
 | 
					 | 
				
			||||||
            label="Initials "
 | 
					 | 
				
			||||||
          />
 | 
					 | 
				
			||||||
          <Input defaultValue={profile.username ?? ''} width="100%" label="Username " />
 | 
					 | 
				
			||||||
          <Input width="100%" label="Email" />
 | 
					 | 
				
			||||||
          <Input width="100%" label="Bio" />
 | 
					 | 
				
			||||||
          <SettingActions>
 | 
					 | 
				
			||||||
            <SaveButton>Save Change</SaveButton>
 | 
					 | 
				
			||||||
          </SettingActions>
 | 
					 | 
				
			||||||
        </Tab>
 | 
					        </Tab>
 | 
				
			||||||
        <Tab tab={1} currentTab={currentTab}>
 | 
					        <Tab tab={1} currentTab={currentTab}>
 | 
				
			||||||
          <ResetPasswordTab onResetPassword={onResetPassword} />
 | 
					          <ResetPasswordTab onResetPassword={onResetPassword} />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,6 +105,7 @@ export type UserAccount = {
 | 
				
			|||||||
  createdAt: Scalars['Time'];
 | 
					  createdAt: Scalars['Time'];
 | 
				
			||||||
  fullName: Scalars['String'];
 | 
					  fullName: Scalars['String'];
 | 
				
			||||||
  initials: Scalars['String'];
 | 
					  initials: Scalars['String'];
 | 
				
			||||||
 | 
					  bio: Scalars['String'];
 | 
				
			||||||
  role: Role;
 | 
					  role: Role;
 | 
				
			||||||
  username: Scalars['String'];
 | 
					  username: Scalars['String'];
 | 
				
			||||||
  profileIcon: ProfileIcon;
 | 
					  profileIcon: ProfileIcon;
 | 
				
			||||||
@@ -303,6 +304,7 @@ export type Mutation = {
 | 
				
			|||||||
  updateTaskLocation: UpdateTaskLocationPayload;
 | 
					  updateTaskLocation: UpdateTaskLocationPayload;
 | 
				
			||||||
  updateTaskName: Task;
 | 
					  updateTaskName: Task;
 | 
				
			||||||
  updateTeamMemberRole: UpdateTeamMemberRolePayload;
 | 
					  updateTeamMemberRole: UpdateTeamMemberRolePayload;
 | 
				
			||||||
 | 
					  updateUserInfo: UpdateUserInfoPayload;
 | 
				
			||||||
  updateUserPassword: UpdateUserPasswordPayload;
 | 
					  updateUserPassword: UpdateUserPasswordPayload;
 | 
				
			||||||
  updateUserRole: UpdateUserRolePayload;
 | 
					  updateUserRole: UpdateUserRolePayload;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -548,6 +550,11 @@ export type MutationUpdateTeamMemberRoleArgs = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type MutationUpdateUserInfoArgs = {
 | 
				
			||||||
 | 
					  input: UpdateUserInfo;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type MutationUpdateUserPasswordArgs = {
 | 
					export type MutationUpdateUserPasswordArgs = {
 | 
				
			||||||
  input: UpdateUserPassword;
 | 
					  input: UpdateUserPassword;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -979,6 +986,18 @@ export type UpdateTeamMemberRolePayload = {
 | 
				
			|||||||
  member: Member;
 | 
					  member: Member;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type UpdateUserInfoPayload = {
 | 
				
			||||||
 | 
					   __typename?: 'UpdateUserInfoPayload';
 | 
				
			||||||
 | 
					  user: UserAccount;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type UpdateUserInfo = {
 | 
				
			||||||
 | 
					  name: Scalars['String'];
 | 
				
			||||||
 | 
					  initials: Scalars['String'];
 | 
				
			||||||
 | 
					  email: Scalars['String'];
 | 
				
			||||||
 | 
					  bio: Scalars['String'];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type UpdateUserPassword = {
 | 
					export type UpdateUserPassword = {
 | 
				
			||||||
  userID: Scalars['UUID'];
 | 
					  userID: Scalars['UUID'];
 | 
				
			||||||
  password: Scalars['String'];
 | 
					  password: Scalars['String'];
 | 
				
			||||||
@@ -1354,7 +1373,7 @@ export type MeQuery = (
 | 
				
			|||||||
    { __typename?: 'MePayload' }
 | 
					    { __typename?: 'MePayload' }
 | 
				
			||||||
    & { user: (
 | 
					    & { user: (
 | 
				
			||||||
      { __typename?: 'UserAccount' }
 | 
					      { __typename?: 'UserAccount' }
 | 
				
			||||||
      & Pick<UserAccount, 'id' | 'fullName'>
 | 
					      & Pick<UserAccount, 'id' | 'fullName' | 'username' | 'email' | 'bio'>
 | 
				
			||||||
      & { profileIcon: (
 | 
					      & { profileIcon: (
 | 
				
			||||||
        { __typename?: 'ProfileIcon' }
 | 
					        { __typename?: 'ProfileIcon' }
 | 
				
			||||||
        & Pick<ProfileIcon, 'initials' | 'bgColor' | 'url'>
 | 
					        & Pick<ProfileIcon, 'initials' | 'bgColor' | 'url'>
 | 
				
			||||||
@@ -2080,7 +2099,7 @@ export type CreateUserAccountMutation = (
 | 
				
			|||||||
  { __typename?: 'Mutation' }
 | 
					  { __typename?: 'Mutation' }
 | 
				
			||||||
  & { createUserAccount: (
 | 
					  & { createUserAccount: (
 | 
				
			||||||
    { __typename?: 'UserAccount' }
 | 
					    { __typename?: 'UserAccount' }
 | 
				
			||||||
    & Pick<UserAccount, 'id' | 'email' | 'fullName' | 'initials' | 'username'>
 | 
					    & Pick<UserAccount, 'id' | 'email' | 'fullName' | 'initials' | 'username' | 'bio'>
 | 
				
			||||||
    & { profileIcon: (
 | 
					    & { profileIcon: (
 | 
				
			||||||
      { __typename?: 'ProfileIcon' }
 | 
					      { __typename?: 'ProfileIcon' }
 | 
				
			||||||
      & Pick<ProfileIcon, 'url' | 'initials' | 'bgColor'>
 | 
					      & Pick<ProfileIcon, 'url' | 'initials' | 'bgColor'>
 | 
				
			||||||
@@ -2127,6 +2146,29 @@ export type DeleteUserAccountMutation = (
 | 
				
			|||||||
  ) }
 | 
					  ) }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type UpdateUserInfoMutationVariables = {
 | 
				
			||||||
 | 
					  name: Scalars['String'];
 | 
				
			||||||
 | 
					  initials: Scalars['String'];
 | 
				
			||||||
 | 
					  email: Scalars['String'];
 | 
				
			||||||
 | 
					  bio: Scalars['String'];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type UpdateUserInfoMutation = (
 | 
				
			||||||
 | 
					  { __typename?: 'Mutation' }
 | 
				
			||||||
 | 
					  & { updateUserInfo: (
 | 
				
			||||||
 | 
					    { __typename?: 'UpdateUserInfoPayload' }
 | 
				
			||||||
 | 
					    & { user: (
 | 
				
			||||||
 | 
					      { __typename?: 'UserAccount' }
 | 
				
			||||||
 | 
					      & Pick<UserAccount, 'id' | 'email' | 'fullName' | 'bio'>
 | 
				
			||||||
 | 
					      & { profileIcon: (
 | 
				
			||||||
 | 
					        { __typename?: 'ProfileIcon' }
 | 
				
			||||||
 | 
					        & Pick<ProfileIcon, 'initials'>
 | 
				
			||||||
 | 
					      ) }
 | 
				
			||||||
 | 
					    ) }
 | 
				
			||||||
 | 
					  ) }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type UpdateUserPasswordMutationVariables = {
 | 
					export type UpdateUserPasswordMutationVariables = {
 | 
				
			||||||
  userID: Scalars['UUID'];
 | 
					  userID: Scalars['UUID'];
 | 
				
			||||||
  password: Scalars['String'];
 | 
					  password: Scalars['String'];
 | 
				
			||||||
@@ -2795,6 +2837,9 @@ export const MeDocument = gql`
 | 
				
			|||||||
    user {
 | 
					    user {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
      fullName
 | 
					      fullName
 | 
				
			||||||
 | 
					      username
 | 
				
			||||||
 | 
					      email
 | 
				
			||||||
 | 
					      bio
 | 
				
			||||||
      profileIcon {
 | 
					      profileIcon {
 | 
				
			||||||
        initials
 | 
					        initials
 | 
				
			||||||
        bgColor
 | 
					        bgColor
 | 
				
			||||||
@@ -4271,6 +4316,7 @@ export const CreateUserAccountDocument = gql`
 | 
				
			|||||||
    fullName
 | 
					    fullName
 | 
				
			||||||
    initials
 | 
					    initials
 | 
				
			||||||
    username
 | 
					    username
 | 
				
			||||||
 | 
					    bio
 | 
				
			||||||
    profileIcon {
 | 
					    profileIcon {
 | 
				
			||||||
      url
 | 
					      url
 | 
				
			||||||
      initials
 | 
					      initials
 | 
				
			||||||
@@ -4369,6 +4415,49 @@ export function useDeleteUserAccountMutation(baseOptions?: ApolloReactHooks.Muta
 | 
				
			|||||||
export type DeleteUserAccountMutationHookResult = ReturnType<typeof useDeleteUserAccountMutation>;
 | 
					export type DeleteUserAccountMutationHookResult = ReturnType<typeof useDeleteUserAccountMutation>;
 | 
				
			||||||
export type DeleteUserAccountMutationResult = ApolloReactCommon.MutationResult<DeleteUserAccountMutation>;
 | 
					export type DeleteUserAccountMutationResult = ApolloReactCommon.MutationResult<DeleteUserAccountMutation>;
 | 
				
			||||||
export type DeleteUserAccountMutationOptions = ApolloReactCommon.BaseMutationOptions<DeleteUserAccountMutation, DeleteUserAccountMutationVariables>;
 | 
					export type DeleteUserAccountMutationOptions = ApolloReactCommon.BaseMutationOptions<DeleteUserAccountMutation, DeleteUserAccountMutationVariables>;
 | 
				
			||||||
 | 
					export const UpdateUserInfoDocument = gql`
 | 
				
			||||||
 | 
					    mutation updateUserInfo($name: String!, $initials: String!, $email: String!, $bio: String!) {
 | 
				
			||||||
 | 
					  updateUserInfo(input: {name: $name, initials: $initials, email: $email, bio: $bio}) {
 | 
				
			||||||
 | 
					    user {
 | 
				
			||||||
 | 
					      id
 | 
				
			||||||
 | 
					      email
 | 
				
			||||||
 | 
					      fullName
 | 
				
			||||||
 | 
					      bio
 | 
				
			||||||
 | 
					      profileIcon {
 | 
				
			||||||
 | 
					        initials
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
 | 
					export type UpdateUserInfoMutationFn = ApolloReactCommon.MutationFunction<UpdateUserInfoMutation, UpdateUserInfoMutationVariables>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * __useUpdateUserInfoMutation__
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * To run a mutation, you first call `useUpdateUserInfoMutation` within a React component and pass it any options that fit your needs.
 | 
				
			||||||
 | 
					 * When your component renders, `useUpdateUserInfoMutation` returns a tuple that includes:
 | 
				
			||||||
 | 
					 * - A mutate function that you can call at any time to execute the mutation
 | 
				
			||||||
 | 
					 * - An object with fields that represent the current status of the mutation's execution
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @example
 | 
				
			||||||
 | 
					 * const [updateUserInfoMutation, { data, loading, error }] = useUpdateUserInfoMutation({
 | 
				
			||||||
 | 
					 *   variables: {
 | 
				
			||||||
 | 
					 *      name: // value for 'name'
 | 
				
			||||||
 | 
					 *      initials: // value for 'initials'
 | 
				
			||||||
 | 
					 *      email: // value for 'email'
 | 
				
			||||||
 | 
					 *      bio: // value for 'bio'
 | 
				
			||||||
 | 
					 *   },
 | 
				
			||||||
 | 
					 * });
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function useUpdateUserInfoMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<UpdateUserInfoMutation, UpdateUserInfoMutationVariables>) {
 | 
				
			||||||
 | 
					        return ApolloReactHooks.useMutation<UpdateUserInfoMutation, UpdateUserInfoMutationVariables>(UpdateUserInfoDocument, baseOptions);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					export type UpdateUserInfoMutationHookResult = ReturnType<typeof useUpdateUserInfoMutation>;
 | 
				
			||||||
 | 
					export type UpdateUserInfoMutationResult = ApolloReactCommon.MutationResult<UpdateUserInfoMutation>;
 | 
				
			||||||
 | 
					export type UpdateUserInfoMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateUserInfoMutation, UpdateUserInfoMutationVariables>;
 | 
				
			||||||
export const UpdateUserPasswordDocument = gql`
 | 
					export const UpdateUserPasswordDocument = gql`
 | 
				
			||||||
    mutation updateUserPassword($userID: UUID!, $password: String!) {
 | 
					    mutation updateUserPassword($userID: UUID!, $password: String!) {
 | 
				
			||||||
  updateUserPassword(input: {userID: $userID, password: $password}) {
 | 
					  updateUserPassword(input: {userID: $userID, password: $password}) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,9 @@ query me {
 | 
				
			|||||||
    user {
 | 
					    user {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
      fullName
 | 
					      fullName
 | 
				
			||||||
 | 
					      username
 | 
				
			||||||
 | 
					      email
 | 
				
			||||||
 | 
					      bio
 | 
				
			||||||
      profileIcon {
 | 
					      profileIcon {
 | 
				
			||||||
        initials
 | 
					        initials
 | 
				
			||||||
        bgColor
 | 
					        bgColor
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@ export const CREATE_USER_MUTATION = gql`
 | 
				
			|||||||
      fullName
 | 
					      fullName
 | 
				
			||||||
      initials
 | 
					      initials
 | 
				
			||||||
      username
 | 
					      username
 | 
				
			||||||
 | 
					      bio
 | 
				
			||||||
      profileIcon {
 | 
					      profileIcon {
 | 
				
			||||||
        url
 | 
					        url
 | 
				
			||||||
        initials
 | 
					        initials
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								frontend/src/shared/graphql/user/updateUserInfo.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								frontend/src/shared/graphql/user/updateUserInfo.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					import gql from 'graphql-tag';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const UPDATE_USER_INFO_MUTATION = gql`
 | 
				
			||||||
 | 
					  mutation updateUserInfo($name: String!, $initials: String!, $email: String!, $bio: String!) {
 | 
				
			||||||
 | 
					    updateUserInfo(input: { name: $name, initials: $initials, email: $email, bio: $bio }) {
 | 
				
			||||||
 | 
					      user {
 | 
				
			||||||
 | 
					        id
 | 
				
			||||||
 | 
					        email
 | 
				
			||||||
 | 
					        fullName
 | 
				
			||||||
 | 
					        bio
 | 
				
			||||||
 | 
					        profileIcon {
 | 
				
			||||||
 | 
					          initials
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default UPDATE_USER_INFO_MUTATION;
 | 
				
			||||||
							
								
								
									
										2
									
								
								frontend/src/taskcafe.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								frontend/src/taskcafe.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -46,6 +46,8 @@ type OwnedList = {
 | 
				
			|||||||
type TaskUser = {
 | 
					type TaskUser = {
 | 
				
			||||||
  id: string;
 | 
					  id: string;
 | 
				
			||||||
  fullName: string;
 | 
					  fullName: string;
 | 
				
			||||||
 | 
					  email?: string;
 | 
				
			||||||
 | 
					  bio?: string;
 | 
				
			||||||
  profileIcon: ProfileIcon;
 | 
					  profileIcon: ProfileIcon;
 | 
				
			||||||
  username?: string;
 | 
					  username?: string;
 | 
				
			||||||
  role?: Role;
 | 
					  role?: Role;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -157,4 +157,5 @@ type UserAccount struct {
 | 
				
			|||||||
	Initials         string         `json:"initials"`
 | 
						Initials         string         `json:"initials"`
 | 
				
			||||||
	ProfileAvatarUrl sql.NullString `json:"profile_avatar_url"`
 | 
						ProfileAvatarUrl sql.NullString `json:"profile_avatar_url"`
 | 
				
			||||||
	RoleCode         string         `json:"role_code"`
 | 
						RoleCode         string         `json:"role_code"`
 | 
				
			||||||
 | 
						Bio              string         `json:"bio"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -114,6 +114,7 @@ type Querier interface {
 | 
				
			|||||||
	UpdateTaskName(ctx context.Context, arg UpdateTaskNameParams) (Task, error)
 | 
						UpdateTaskName(ctx context.Context, arg UpdateTaskNameParams) (Task, error)
 | 
				
			||||||
	UpdateTaskPosition(ctx context.Context, arg UpdateTaskPositionParams) (Task, error)
 | 
						UpdateTaskPosition(ctx context.Context, arg UpdateTaskPositionParams) (Task, error)
 | 
				
			||||||
	UpdateTeamMemberRole(ctx context.Context, arg UpdateTeamMemberRoleParams) (TeamMember, error)
 | 
						UpdateTeamMemberRole(ctx context.Context, arg UpdateTeamMemberRoleParams) (TeamMember, error)
 | 
				
			||||||
 | 
						UpdateUserAccountInfo(ctx context.Context, arg UpdateUserAccountInfoParams) (UserAccount, error)
 | 
				
			||||||
	UpdateUserAccountProfileAvatarURL(ctx context.Context, arg UpdateUserAccountProfileAvatarURLParams) (UserAccount, error)
 | 
						UpdateUserAccountProfileAvatarURL(ctx context.Context, arg UpdateUserAccountProfileAvatarURLParams) (UserAccount, error)
 | 
				
			||||||
	UpdateUserRole(ctx context.Context, arg UpdateUserRoleParams) (UserAccount, error)
 | 
						UpdateUserRole(ctx context.Context, arg UpdateUserRoleParams) (UserAccount, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,10 @@ INSERT INTO user_account(full_name, initials, email, username, created_at, passw
 | 
				
			|||||||
UPDATE user_account SET profile_avatar_url = $2 WHERE user_id = $1
 | 
					UPDATE user_account SET profile_avatar_url = $2 WHERE user_id = $1
 | 
				
			||||||
  RETURNING *;
 | 
					  RETURNING *;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- name: UpdateUserAccountInfo :one
 | 
				
			||||||
 | 
					UPDATE user_account SET bio = $2, full_name = $3, initials = $4, email = $5
 | 
				
			||||||
 | 
					  WHERE user_id = $1 RETURNING *;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- name: DeleteUserAccountByID :exec
 | 
					-- name: DeleteUserAccountByID :exec
 | 
				
			||||||
DELETE FROM user_account WHERE user_id = $1;
 | 
					DELETE FROM user_account WHERE user_id = $1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const createUserAccount = `-- name: CreateUserAccount :one
 | 
					const createUserAccount = `-- name: CreateUserAccount :one
 | 
				
			||||||
INSERT INTO user_account(full_name, initials, email, username, created_at, password_hash, role_code)
 | 
					INSERT INTO user_account(full_name, initials, email, username, created_at, password_hash, role_code)
 | 
				
			||||||
  VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code
 | 
					  VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code, bio
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CreateUserAccountParams struct {
 | 
					type CreateUserAccountParams struct {
 | 
				
			||||||
@@ -48,6 +48,7 @@ func (q *Queries) CreateUserAccount(ctx context.Context, arg CreateUserAccountPa
 | 
				
			|||||||
		&i.Initials,
 | 
							&i.Initials,
 | 
				
			||||||
		&i.ProfileAvatarUrl,
 | 
							&i.ProfileAvatarUrl,
 | 
				
			||||||
		&i.RoleCode,
 | 
							&i.RoleCode,
 | 
				
			||||||
 | 
							&i.Bio,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -62,7 +63,7 @@ func (q *Queries) DeleteUserAccountByID(ctx context.Context, userID uuid.UUID) e
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getAllUserAccounts = `-- name: GetAllUserAccounts :many
 | 
					const getAllUserAccounts = `-- name: GetAllUserAccounts :many
 | 
				
			||||||
SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code FROM user_account WHERE username != 'system'
 | 
					SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code, bio FROM user_account WHERE username != 'system'
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q *Queries) GetAllUserAccounts(ctx context.Context) ([]UserAccount, error) {
 | 
					func (q *Queries) GetAllUserAccounts(ctx context.Context) ([]UserAccount, error) {
 | 
				
			||||||
@@ -85,6 +86,7 @@ func (q *Queries) GetAllUserAccounts(ctx context.Context) ([]UserAccount, error)
 | 
				
			|||||||
			&i.Initials,
 | 
								&i.Initials,
 | 
				
			||||||
			&i.ProfileAvatarUrl,
 | 
								&i.ProfileAvatarUrl,
 | 
				
			||||||
			&i.RoleCode,
 | 
								&i.RoleCode,
 | 
				
			||||||
 | 
								&i.Bio,
 | 
				
			||||||
		); err != nil {
 | 
							); err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -119,7 +121,7 @@ func (q *Queries) GetRoleForUserID(ctx context.Context, userID uuid.UUID) (GetRo
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getUserAccountByID = `-- name: GetUserAccountByID :one
 | 
					const getUserAccountByID = `-- name: GetUserAccountByID :one
 | 
				
			||||||
SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code FROM user_account WHERE user_id = $1
 | 
					SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code, bio FROM user_account WHERE user_id = $1
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q *Queries) GetUserAccountByID(ctx context.Context, userID uuid.UUID) (UserAccount, error) {
 | 
					func (q *Queries) GetUserAccountByID(ctx context.Context, userID uuid.UUID) (UserAccount, error) {
 | 
				
			||||||
@@ -136,12 +138,13 @@ func (q *Queries) GetUserAccountByID(ctx context.Context, userID uuid.UUID) (Use
 | 
				
			|||||||
		&i.Initials,
 | 
							&i.Initials,
 | 
				
			||||||
		&i.ProfileAvatarUrl,
 | 
							&i.ProfileAvatarUrl,
 | 
				
			||||||
		&i.RoleCode,
 | 
							&i.RoleCode,
 | 
				
			||||||
 | 
							&i.Bio,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getUserAccountByUsername = `-- name: GetUserAccountByUsername :one
 | 
					const getUserAccountByUsername = `-- name: GetUserAccountByUsername :one
 | 
				
			||||||
SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code FROM user_account WHERE username = $1
 | 
					SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code, bio FROM user_account WHERE username = $1
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q *Queries) GetUserAccountByUsername(ctx context.Context, username string) (UserAccount, error) {
 | 
					func (q *Queries) GetUserAccountByUsername(ctx context.Context, username string) (UserAccount, error) {
 | 
				
			||||||
@@ -158,12 +161,13 @@ func (q *Queries) GetUserAccountByUsername(ctx context.Context, username string)
 | 
				
			|||||||
		&i.Initials,
 | 
							&i.Initials,
 | 
				
			||||||
		&i.ProfileAvatarUrl,
 | 
							&i.ProfileAvatarUrl,
 | 
				
			||||||
		&i.RoleCode,
 | 
							&i.RoleCode,
 | 
				
			||||||
 | 
							&i.Bio,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const setUserPassword = `-- name: SetUserPassword :one
 | 
					const setUserPassword = `-- name: SetUserPassword :one
 | 
				
			||||||
UPDATE user_account SET password_hash = $2 WHERE user_id = $1 RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code
 | 
					UPDATE user_account SET password_hash = $2 WHERE user_id = $1 RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code, bio
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SetUserPasswordParams struct {
 | 
					type SetUserPasswordParams struct {
 | 
				
			||||||
@@ -185,13 +189,52 @@ func (q *Queries) SetUserPassword(ctx context.Context, arg SetUserPasswordParams
 | 
				
			|||||||
		&i.Initials,
 | 
							&i.Initials,
 | 
				
			||||||
		&i.ProfileAvatarUrl,
 | 
							&i.ProfileAvatarUrl,
 | 
				
			||||||
		&i.RoleCode,
 | 
							&i.RoleCode,
 | 
				
			||||||
 | 
							&i.Bio,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						return i, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const updateUserAccountInfo = `-- name: UpdateUserAccountInfo :one
 | 
				
			||||||
 | 
					UPDATE user_account SET bio = $2, full_name = $3, initials = $4, email = $5
 | 
				
			||||||
 | 
					  WHERE user_id = $1 RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code, bio
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateUserAccountInfoParams struct {
 | 
				
			||||||
 | 
						UserID   uuid.UUID `json:"user_id"`
 | 
				
			||||||
 | 
						Bio      string    `json:"bio"`
 | 
				
			||||||
 | 
						FullName string    `json:"full_name"`
 | 
				
			||||||
 | 
						Initials string    `json:"initials"`
 | 
				
			||||||
 | 
						Email    string    `json:"email"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *Queries) UpdateUserAccountInfo(ctx context.Context, arg UpdateUserAccountInfoParams) (UserAccount, error) {
 | 
				
			||||||
 | 
						row := q.db.QueryRowContext(ctx, updateUserAccountInfo,
 | 
				
			||||||
 | 
							arg.UserID,
 | 
				
			||||||
 | 
							arg.Bio,
 | 
				
			||||||
 | 
							arg.FullName,
 | 
				
			||||||
 | 
							arg.Initials,
 | 
				
			||||||
 | 
							arg.Email,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						var i UserAccount
 | 
				
			||||||
 | 
						err := row.Scan(
 | 
				
			||||||
 | 
							&i.UserID,
 | 
				
			||||||
 | 
							&i.CreatedAt,
 | 
				
			||||||
 | 
							&i.Email,
 | 
				
			||||||
 | 
							&i.Username,
 | 
				
			||||||
 | 
							&i.PasswordHash,
 | 
				
			||||||
 | 
							&i.ProfileBgColor,
 | 
				
			||||||
 | 
							&i.FullName,
 | 
				
			||||||
 | 
							&i.Initials,
 | 
				
			||||||
 | 
							&i.ProfileAvatarUrl,
 | 
				
			||||||
 | 
							&i.RoleCode,
 | 
				
			||||||
 | 
							&i.Bio,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const updateUserAccountProfileAvatarURL = `-- name: UpdateUserAccountProfileAvatarURL :one
 | 
					const updateUserAccountProfileAvatarURL = `-- name: UpdateUserAccountProfileAvatarURL :one
 | 
				
			||||||
UPDATE user_account SET profile_avatar_url = $2 WHERE user_id = $1
 | 
					UPDATE user_account SET profile_avatar_url = $2 WHERE user_id = $1
 | 
				
			||||||
  RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code
 | 
					  RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code, bio
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UpdateUserAccountProfileAvatarURLParams struct {
 | 
					type UpdateUserAccountProfileAvatarURLParams struct {
 | 
				
			||||||
@@ -213,12 +256,13 @@ func (q *Queries) UpdateUserAccountProfileAvatarURL(ctx context.Context, arg Upd
 | 
				
			|||||||
		&i.Initials,
 | 
							&i.Initials,
 | 
				
			||||||
		&i.ProfileAvatarUrl,
 | 
							&i.ProfileAvatarUrl,
 | 
				
			||||||
		&i.RoleCode,
 | 
							&i.RoleCode,
 | 
				
			||||||
 | 
							&i.Bio,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const updateUserRole = `-- name: UpdateUserRole :one
 | 
					const updateUserRole = `-- name: UpdateUserRole :one
 | 
				
			||||||
UPDATE user_account SET role_code = $2 WHERE user_id = $1 RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code
 | 
					UPDATE user_account SET role_code = $2 WHERE user_id = $1 RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code, bio
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UpdateUserRoleParams struct {
 | 
					type UpdateUserRoleParams struct {
 | 
				
			||||||
@@ -240,6 +284,7 @@ func (q *Queries) UpdateUserRole(ctx context.Context, arg UpdateUserRoleParams)
 | 
				
			|||||||
		&i.Initials,
 | 
							&i.Initials,
 | 
				
			||||||
		&i.ProfileAvatarUrl,
 | 
							&i.ProfileAvatarUrl,
 | 
				
			||||||
		&i.RoleCode,
 | 
							&i.RoleCode,
 | 
				
			||||||
 | 
							&i.Bio,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -210,6 +210,7 @@ type ComplexityRoot struct {
 | 
				
			|||||||
		UpdateTaskLocation              func(childComplexity int, input NewTaskLocation) int
 | 
							UpdateTaskLocation              func(childComplexity int, input NewTaskLocation) int
 | 
				
			||||||
		UpdateTaskName                  func(childComplexity int, input UpdateTaskName) int
 | 
							UpdateTaskName                  func(childComplexity int, input UpdateTaskName) int
 | 
				
			||||||
		UpdateTeamMemberRole            func(childComplexity int, input UpdateTeamMemberRole) int
 | 
							UpdateTeamMemberRole            func(childComplexity int, input UpdateTeamMemberRole) int
 | 
				
			||||||
 | 
							UpdateUserInfo                  func(childComplexity int, input UpdateUserInfo) int
 | 
				
			||||||
		UpdateUserPassword              func(childComplexity int, input UpdateUserPassword) int
 | 
							UpdateUserPassword              func(childComplexity int, input UpdateUserPassword) int
 | 
				
			||||||
		UpdateUserRole                  func(childComplexity int, input UpdateUserRole) int
 | 
							UpdateUserRole                  func(childComplexity int, input UpdateUserRole) int
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -404,6 +405,10 @@ type ComplexityRoot struct {
 | 
				
			|||||||
		TeamID func(childComplexity int) int
 | 
							TeamID func(childComplexity int) int
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						UpdateUserInfoPayload struct {
 | 
				
			||||||
 | 
							User func(childComplexity int) int
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	UpdateUserPasswordPayload struct {
 | 
						UpdateUserPasswordPayload struct {
 | 
				
			||||||
		Ok   func(childComplexity int) int
 | 
							Ok   func(childComplexity int) int
 | 
				
			||||||
		User func(childComplexity int) int
 | 
							User func(childComplexity int) int
 | 
				
			||||||
@@ -414,6 +419,7 @@ type ComplexityRoot struct {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	UserAccount struct {
 | 
						UserAccount struct {
 | 
				
			||||||
 | 
							Bio         func(childComplexity int) int
 | 
				
			||||||
		CreatedAt   func(childComplexity int) int
 | 
							CreatedAt   func(childComplexity int) int
 | 
				
			||||||
		Email       func(childComplexity int) int
 | 
							Email       func(childComplexity int) int
 | 
				
			||||||
		FullName    func(childComplexity int) int
 | 
							FullName    func(childComplexity int) int
 | 
				
			||||||
@@ -482,6 +488,7 @@ type MutationResolver interface {
 | 
				
			|||||||
	ClearProfileAvatar(ctx context.Context) (*db.UserAccount, error)
 | 
						ClearProfileAvatar(ctx context.Context) (*db.UserAccount, error)
 | 
				
			||||||
	UpdateUserPassword(ctx context.Context, input UpdateUserPassword) (*UpdateUserPasswordPayload, error)
 | 
						UpdateUserPassword(ctx context.Context, input UpdateUserPassword) (*UpdateUserPasswordPayload, error)
 | 
				
			||||||
	UpdateUserRole(ctx context.Context, input UpdateUserRole) (*UpdateUserRolePayload, error)
 | 
						UpdateUserRole(ctx context.Context, input UpdateUserRole) (*UpdateUserRolePayload, error)
 | 
				
			||||||
 | 
						UpdateUserInfo(ctx context.Context, input UpdateUserInfo) (*UpdateUserInfoPayload, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
type NotificationResolver interface {
 | 
					type NotificationResolver interface {
 | 
				
			||||||
	ID(ctx context.Context, obj *db.Notification) (uuid.UUID, error)
 | 
						ID(ctx context.Context, obj *db.Notification) (uuid.UUID, error)
 | 
				
			||||||
@@ -1493,6 +1500,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return e.complexity.Mutation.UpdateTeamMemberRole(childComplexity, args["input"].(UpdateTeamMemberRole)), true
 | 
							return e.complexity.Mutation.UpdateTeamMemberRole(childComplexity, args["input"].(UpdateTeamMemberRole)), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case "Mutation.updateUserInfo":
 | 
				
			||||||
 | 
							if e.complexity.Mutation.UpdateUserInfo == nil {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							args, err := ec.field_Mutation_updateUserInfo_args(context.TODO(), rawArgs)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return 0, false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return e.complexity.Mutation.UpdateUserInfo(childComplexity, args["input"].(UpdateUserInfo)), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "Mutation.updateUserPassword":
 | 
						case "Mutation.updateUserPassword":
 | 
				
			||||||
		if e.complexity.Mutation.UpdateUserPassword == nil {
 | 
							if e.complexity.Mutation.UpdateUserPassword == nil {
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
@@ -2284,6 +2303,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return e.complexity.UpdateTeamMemberRolePayload.TeamID(childComplexity), true
 | 
							return e.complexity.UpdateTeamMemberRolePayload.TeamID(childComplexity), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case "UpdateUserInfoPayload.user":
 | 
				
			||||||
 | 
							if e.complexity.UpdateUserInfoPayload.User == nil {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return e.complexity.UpdateUserInfoPayload.User(childComplexity), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "UpdateUserPasswordPayload.ok":
 | 
						case "UpdateUserPasswordPayload.ok":
 | 
				
			||||||
		if e.complexity.UpdateUserPasswordPayload.Ok == nil {
 | 
							if e.complexity.UpdateUserPasswordPayload.Ok == nil {
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
@@ -2305,6 +2331,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return e.complexity.UpdateUserRolePayload.User(childComplexity), true
 | 
							return e.complexity.UpdateUserRolePayload.User(childComplexity), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case "UserAccount.bio":
 | 
				
			||||||
 | 
							if e.complexity.UserAccount.Bio == nil {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return e.complexity.UserAccount.Bio(childComplexity), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "UserAccount.createdAt":
 | 
						case "UserAccount.createdAt":
 | 
				
			||||||
		if e.complexity.UserAccount.CreatedAt == nil {
 | 
							if e.complexity.UserAccount.CreatedAt == nil {
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
@@ -2519,6 +2552,7 @@ type UserAccount {
 | 
				
			|||||||
  createdAt: Time!
 | 
					  createdAt: Time!
 | 
				
			||||||
  fullName: String!
 | 
					  fullName: String!
 | 
				
			||||||
  initials: String!
 | 
					  initials: String!
 | 
				
			||||||
 | 
					  bio: String!
 | 
				
			||||||
  role: Role!
 | 
					  role: Role!
 | 
				
			||||||
  username: String!
 | 
					  username: String!
 | 
				
			||||||
  profileIcon: ProfileIcon!
 | 
					  profileIcon: ProfileIcon!
 | 
				
			||||||
@@ -3163,6 +3197,19 @@ extend type Mutation {
 | 
				
			|||||||
  updateUserPassword(input: UpdateUserPassword!): UpdateUserPasswordPayload!
 | 
					  updateUserPassword(input: UpdateUserPassword!): UpdateUserPasswordPayload!
 | 
				
			||||||
  updateUserRole(input: UpdateUserRole!):
 | 
					  updateUserRole(input: UpdateUserRole!):
 | 
				
			||||||
   UpdateUserRolePayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG)
 | 
					   UpdateUserRolePayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG)
 | 
				
			||||||
 | 
					  updateUserInfo(input: UpdateUserInfo!):
 | 
				
			||||||
 | 
					    UpdateUserInfoPayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateUserInfoPayload {
 | 
				
			||||||
 | 
					  user: UserAccount!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input UpdateUserInfo {
 | 
				
			||||||
 | 
					  name: String!
 | 
				
			||||||
 | 
					  initials: String!
 | 
				
			||||||
 | 
					  email: String!
 | 
				
			||||||
 | 
					  bio: String!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input UpdateUserPassword {
 | 
					input UpdateUserPassword {
 | 
				
			||||||
@@ -3921,6 +3968,20 @@ func (ec *executionContext) field_Mutation_updateTeamMemberRole_args(ctx context
 | 
				
			|||||||
	return args, nil
 | 
						return args, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) field_Mutation_updateUserInfo_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						args := map[string]interface{}{}
 | 
				
			||||||
 | 
						var arg0 UpdateUserInfo
 | 
				
			||||||
 | 
						if tmp, ok := rawArgs["input"]; ok {
 | 
				
			||||||
 | 
							arg0, err = ec.unmarshalNUpdateUserInfo2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐUpdateUserInfo(ctx, tmp)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args["input"] = arg0
 | 
				
			||||||
 | 
						return args, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) field_Mutation_updateUserPassword_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
 | 
					func (ec *executionContext) field_Mutation_updateUserPassword_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	args := map[string]interface{}{}
 | 
						args := map[string]interface{}{}
 | 
				
			||||||
@@ -9221,6 +9282,79 @@ func (ec *executionContext) _Mutation_updateUserRole(ctx context.Context, field
 | 
				
			|||||||
	return ec.marshalNUpdateUserRolePayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐUpdateUserRolePayload(ctx, field.Selections, res)
 | 
						return ec.marshalNUpdateUserRolePayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐUpdateUserRolePayload(ctx, field.Selections, res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) _Mutation_updateUserInfo(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
 | 
								ec.Error(ctx, ec.Recover(ctx, r))
 | 
				
			||||||
 | 
								ret = graphql.Null
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
						fc := &graphql.FieldContext{
 | 
				
			||||||
 | 
							Object:   "Mutation",
 | 
				
			||||||
 | 
							Field:    field,
 | 
				
			||||||
 | 
							Args:     nil,
 | 
				
			||||||
 | 
							IsMethod: true,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = graphql.WithFieldContext(ctx, fc)
 | 
				
			||||||
 | 
						rawArgs := field.ArgumentMap(ec.Variables)
 | 
				
			||||||
 | 
						args, err := ec.field_Mutation_updateUserInfo_args(ctx, rawArgs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fc.Args = args
 | 
				
			||||||
 | 
						resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
				
			||||||
 | 
							directive0 := func(rctx context.Context) (interface{}, error) {
 | 
				
			||||||
 | 
								ctx = rctx // use context from middleware stack in children
 | 
				
			||||||
 | 
								return ec.resolvers.Mutation().UpdateUserInfo(rctx, args["input"].(UpdateUserInfo))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							directive1 := func(ctx context.Context) (interface{}, error) {
 | 
				
			||||||
 | 
								roles, err := ec.unmarshalNRoleLevel2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐRoleLevelᚄ(ctx, []interface{}{"ADMIN"})
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								level, err := ec.unmarshalNActionLevel2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐActionLevel(ctx, "ORG")
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "ORG")
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if ec.directives.HasRole == nil {
 | 
				
			||||||
 | 
									return nil, errors.New("directive hasRole is not implemented")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return ec.directives.HasRole(ctx, nil, directive0, roles, level, typeArg)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tmp, err := directive1(rctx)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if tmp == nil {
 | 
				
			||||||
 | 
								return nil, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if data, ok := tmp.(*UpdateUserInfoPayload); ok {
 | 
				
			||||||
 | 
								return data, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/jordanknott/taskcafe/internal/graph.UpdateUserInfoPayload`, tmp)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if resTmp == nil {
 | 
				
			||||||
 | 
							if !graphql.HasFieldError(ctx, fc) {
 | 
				
			||||||
 | 
								ec.Errorf(ctx, "must not be null")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res := resTmp.(*UpdateUserInfoPayload)
 | 
				
			||||||
 | 
						fc.Result = res
 | 
				
			||||||
 | 
						return ec.marshalNUpdateUserInfoPayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐUpdateUserInfoPayload(ctx, field.Selections, res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _Notification_id(ctx context.Context, field graphql.CollectedField, obj *db.Notification) (ret graphql.Marshaler) {
 | 
					func (ec *executionContext) _Notification_id(ctx context.Context, field graphql.CollectedField, obj *db.Notification) (ret graphql.Marshaler) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
@@ -12905,6 +13039,40 @@ func (ec *executionContext) _UpdateTeamMemberRolePayload_member(ctx context.Cont
 | 
				
			|||||||
	return ec.marshalNMember2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMember(ctx, field.Selections, res)
 | 
						return ec.marshalNMember2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMember(ctx, field.Selections, res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) _UpdateUserInfoPayload_user(ctx context.Context, field graphql.CollectedField, obj *UpdateUserInfoPayload) (ret graphql.Marshaler) {
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
 | 
								ec.Error(ctx, ec.Recover(ctx, r))
 | 
				
			||||||
 | 
								ret = graphql.Null
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
						fc := &graphql.FieldContext{
 | 
				
			||||||
 | 
							Object:   "UpdateUserInfoPayload",
 | 
				
			||||||
 | 
							Field:    field,
 | 
				
			||||||
 | 
							Args:     nil,
 | 
				
			||||||
 | 
							IsMethod: false,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = graphql.WithFieldContext(ctx, fc)
 | 
				
			||||||
 | 
						resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
				
			||||||
 | 
							ctx = rctx // use context from middleware stack in children
 | 
				
			||||||
 | 
							return obj.User, nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if resTmp == nil {
 | 
				
			||||||
 | 
							if !graphql.HasFieldError(ctx, fc) {
 | 
				
			||||||
 | 
								ec.Errorf(ctx, "must not be null")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res := resTmp.(*db.UserAccount)
 | 
				
			||||||
 | 
						fc.Result = res
 | 
				
			||||||
 | 
						return ec.marshalNUserAccount2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐUserAccount(ctx, field.Selections, res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _UpdateUserPasswordPayload_ok(ctx context.Context, field graphql.CollectedField, obj *UpdateUserPasswordPayload) (ret graphql.Marshaler) {
 | 
					func (ec *executionContext) _UpdateUserPasswordPayload_ok(ctx context.Context, field graphql.CollectedField, obj *UpdateUserPasswordPayload) (ret graphql.Marshaler) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
@@ -13177,6 +13345,40 @@ func (ec *executionContext) _UserAccount_initials(ctx context.Context, field gra
 | 
				
			|||||||
	return ec.marshalNString2string(ctx, field.Selections, res)
 | 
						return ec.marshalNString2string(ctx, field.Selections, res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) _UserAccount_bio(ctx context.Context, field graphql.CollectedField, obj *db.UserAccount) (ret graphql.Marshaler) {
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
 | 
								ec.Error(ctx, ec.Recover(ctx, r))
 | 
				
			||||||
 | 
								ret = graphql.Null
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
						fc := &graphql.FieldContext{
 | 
				
			||||||
 | 
							Object:   "UserAccount",
 | 
				
			||||||
 | 
							Field:    field,
 | 
				
			||||||
 | 
							Args:     nil,
 | 
				
			||||||
 | 
							IsMethod: false,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = graphql.WithFieldContext(ctx, fc)
 | 
				
			||||||
 | 
						resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
				
			||||||
 | 
							ctx = rctx // use context from middleware stack in children
 | 
				
			||||||
 | 
							return obj.Bio, nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if resTmp == nil {
 | 
				
			||||||
 | 
							if !graphql.HasFieldError(ctx, fc) {
 | 
				
			||||||
 | 
								ec.Errorf(ctx, "must not be null")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res := resTmp.(string)
 | 
				
			||||||
 | 
						fc.Result = res
 | 
				
			||||||
 | 
						return ec.marshalNString2string(ctx, field.Selections, res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _UserAccount_role(ctx context.Context, field graphql.CollectedField, obj *db.UserAccount) (ret graphql.Marshaler) {
 | 
					func (ec *executionContext) _UserAccount_role(ctx context.Context, field graphql.CollectedField, obj *db.UserAccount) (ret graphql.Marshaler) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
@@ -15710,6 +15912,42 @@ func (ec *executionContext) unmarshalInputUpdateTeamMemberRole(ctx context.Conte
 | 
				
			|||||||
	return it, nil
 | 
						return it, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) unmarshalInputUpdateUserInfo(ctx context.Context, obj interface{}) (UpdateUserInfo, error) {
 | 
				
			||||||
 | 
						var it UpdateUserInfo
 | 
				
			||||||
 | 
						var asMap = obj.(map[string]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for k, v := range asMap {
 | 
				
			||||||
 | 
							switch k {
 | 
				
			||||||
 | 
							case "name":
 | 
				
			||||||
 | 
								var err error
 | 
				
			||||||
 | 
								it.Name, err = ec.unmarshalNString2string(ctx, v)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return it, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case "initials":
 | 
				
			||||||
 | 
								var err error
 | 
				
			||||||
 | 
								it.Initials, err = ec.unmarshalNString2string(ctx, v)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return it, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case "email":
 | 
				
			||||||
 | 
								var err error
 | 
				
			||||||
 | 
								it.Email, err = ec.unmarshalNString2string(ctx, v)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return it, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case "bio":
 | 
				
			||||||
 | 
								var err error
 | 
				
			||||||
 | 
								it.Bio, err = ec.unmarshalNString2string(ctx, v)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return it, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return it, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) unmarshalInputUpdateUserPassword(ctx context.Context, obj interface{}) (UpdateUserPassword, error) {
 | 
					func (ec *executionContext) unmarshalInputUpdateUserPassword(ctx context.Context, obj interface{}) (UpdateUserPassword, error) {
 | 
				
			||||||
	var it UpdateUserPassword
 | 
						var it UpdateUserPassword
 | 
				
			||||||
	var asMap = obj.(map[string]interface{})
 | 
						var asMap = obj.(map[string]interface{})
 | 
				
			||||||
@@ -16671,6 +16909,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
 | 
				
			|||||||
			if out.Values[i] == graphql.Null {
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
				invalids++
 | 
									invalids++
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							case "updateUserInfo":
 | 
				
			||||||
 | 
								out.Values[i] = ec._Mutation_updateUserInfo(ctx, field)
 | 
				
			||||||
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
 | 
									invalids++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			panic("unknown field " + strconv.Quote(field.Name))
 | 
								panic("unknown field " + strconv.Quote(field.Name))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -18235,6 +18478,33 @@ func (ec *executionContext) _UpdateTeamMemberRolePayload(ctx context.Context, se
 | 
				
			|||||||
	return out
 | 
						return out
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var updateUserInfoPayloadImplementors = []string{"UpdateUserInfoPayload"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) _UpdateUserInfoPayload(ctx context.Context, sel ast.SelectionSet, obj *UpdateUserInfoPayload) graphql.Marshaler {
 | 
				
			||||||
 | 
						fields := graphql.CollectFields(ec.OperationContext, sel, updateUserInfoPayloadImplementors)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						out := graphql.NewFieldSet(fields)
 | 
				
			||||||
 | 
						var invalids uint32
 | 
				
			||||||
 | 
						for i, field := range fields {
 | 
				
			||||||
 | 
							switch field.Name {
 | 
				
			||||||
 | 
							case "__typename":
 | 
				
			||||||
 | 
								out.Values[i] = graphql.MarshalString("UpdateUserInfoPayload")
 | 
				
			||||||
 | 
							case "user":
 | 
				
			||||||
 | 
								out.Values[i] = ec._UpdateUserInfoPayload_user(ctx, field, obj)
 | 
				
			||||||
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
 | 
									invalids++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								panic("unknown field " + strconv.Quote(field.Name))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						out.Dispatch()
 | 
				
			||||||
 | 
						if invalids > 0 {
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return out
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var updateUserPasswordPayloadImplementors = []string{"UpdateUserPasswordPayload"}
 | 
					var updateUserPasswordPayloadImplementors = []string{"UpdateUserPasswordPayload"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _UpdateUserPasswordPayload(ctx context.Context, sel ast.SelectionSet, obj *UpdateUserPasswordPayload) graphql.Marshaler {
 | 
					func (ec *executionContext) _UpdateUserPasswordPayload(ctx context.Context, sel ast.SelectionSet, obj *UpdateUserPasswordPayload) graphql.Marshaler {
 | 
				
			||||||
@@ -18339,6 +18609,11 @@ func (ec *executionContext) _UserAccount(ctx context.Context, sel ast.SelectionS
 | 
				
			|||||||
			if out.Values[i] == graphql.Null {
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
				atomic.AddUint32(&invalids, 1)
 | 
									atomic.AddUint32(&invalids, 1)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							case "bio":
 | 
				
			||||||
 | 
								out.Values[i] = ec._UserAccount_bio(ctx, field, obj)
 | 
				
			||||||
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
 | 
									atomic.AddUint32(&invalids, 1)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		case "role":
 | 
							case "role":
 | 
				
			||||||
			field := field
 | 
								field := field
 | 
				
			||||||
			out.Concurrently(i, func() (res graphql.Marshaler) {
 | 
								out.Concurrently(i, func() (res graphql.Marshaler) {
 | 
				
			||||||
@@ -20203,6 +20478,24 @@ func (ec *executionContext) marshalNUpdateTeamMemberRolePayload2ᚖgithubᚗcom
 | 
				
			|||||||
	return ec._UpdateTeamMemberRolePayload(ctx, sel, v)
 | 
						return ec._UpdateTeamMemberRolePayload(ctx, sel, v)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) unmarshalNUpdateUserInfo2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐUpdateUserInfo(ctx context.Context, v interface{}) (UpdateUserInfo, error) {
 | 
				
			||||||
 | 
						return ec.unmarshalInputUpdateUserInfo(ctx, v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) marshalNUpdateUserInfoPayload2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐUpdateUserInfoPayload(ctx context.Context, sel ast.SelectionSet, v UpdateUserInfoPayload) graphql.Marshaler {
 | 
				
			||||||
 | 
						return ec._UpdateUserInfoPayload(ctx, sel, &v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) marshalNUpdateUserInfoPayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐUpdateUserInfoPayload(ctx context.Context, sel ast.SelectionSet, v *UpdateUserInfoPayload) graphql.Marshaler {
 | 
				
			||||||
 | 
						if v == nil {
 | 
				
			||||||
 | 
							if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
 | 
				
			||||||
 | 
								ec.Errorf(ctx, "must not be null")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ec._UpdateUserInfoPayload(ctx, sel, v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) unmarshalNUpdateUserPassword2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐUpdateUserPassword(ctx context.Context, v interface{}) (UpdateUserPassword, error) {
 | 
					func (ec *executionContext) unmarshalNUpdateUserPassword2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐUpdateUserPassword(ctx context.Context, v interface{}) (UpdateUserPassword, error) {
 | 
				
			||||||
	return ec.unmarshalInputUpdateUserPassword(ctx, v)
 | 
						return ec.unmarshalInputUpdateUserPassword(ctx, v)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -455,6 +455,17 @@ type UpdateTeamMemberRolePayload struct {
 | 
				
			|||||||
	Member *Member   `json:"member"`
 | 
						Member *Member   `json:"member"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateUserInfo struct {
 | 
				
			||||||
 | 
						Name     string `json:"name"`
 | 
				
			||||||
 | 
						Initials string `json:"initials"`
 | 
				
			||||||
 | 
						Email    string `json:"email"`
 | 
				
			||||||
 | 
						Bio      string `json:"bio"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateUserInfoPayload struct {
 | 
				
			||||||
 | 
						User *db.UserAccount `json:"user"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UpdateUserPassword struct {
 | 
					type UpdateUserPassword struct {
 | 
				
			||||||
	UserID   uuid.UUID `json:"userID"`
 | 
						UserID   uuid.UUID `json:"userID"`
 | 
				
			||||||
	Password string    `json:"password"`
 | 
						Password string    `json:"password"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,6 +78,7 @@ type UserAccount {
 | 
				
			|||||||
  createdAt: Time!
 | 
					  createdAt: Time!
 | 
				
			||||||
  fullName: String!
 | 
					  fullName: String!
 | 
				
			||||||
  initials: String!
 | 
					  initials: String!
 | 
				
			||||||
 | 
					  bio: String!
 | 
				
			||||||
  role: Role!
 | 
					  role: Role!
 | 
				
			||||||
  username: String!
 | 
					  username: String!
 | 
				
			||||||
  profileIcon: ProfileIcon!
 | 
					  profileIcon: ProfileIcon!
 | 
				
			||||||
@@ -722,6 +723,19 @@ extend type Mutation {
 | 
				
			|||||||
  updateUserPassword(input: UpdateUserPassword!): UpdateUserPasswordPayload!
 | 
					  updateUserPassword(input: UpdateUserPassword!): UpdateUserPasswordPayload!
 | 
				
			||||||
  updateUserRole(input: UpdateUserRole!):
 | 
					  updateUserRole(input: UpdateUserRole!):
 | 
				
			||||||
   UpdateUserRolePayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG)
 | 
					   UpdateUserRolePayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG)
 | 
				
			||||||
 | 
					  updateUserInfo(input: UpdateUserInfo!):
 | 
				
			||||||
 | 
					    UpdateUserInfoPayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateUserInfoPayload {
 | 
				
			||||||
 | 
					  user: UserAccount!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input UpdateUserInfo {
 | 
				
			||||||
 | 
					  name: String!
 | 
				
			||||||
 | 
					  initials: String!
 | 
				
			||||||
 | 
					  email: String!
 | 
				
			||||||
 | 
					  bio: String!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input UpdateUserPassword {
 | 
					input UpdateUserPassword {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -826,6 +826,17 @@ func (r *mutationResolver) UpdateUserRole(ctx context.Context, input UpdateUserR
 | 
				
			|||||||
	return &UpdateUserRolePayload{User: &user}, nil
 | 
						return &UpdateUserRolePayload{User: &user}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *mutationResolver) UpdateUserInfo(ctx context.Context, input UpdateUserInfo) (*UpdateUserInfoPayload, error) {
 | 
				
			||||||
 | 
						userID, ok := GetUserID(ctx)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return &UpdateUserInfoPayload{}, errors.New("invalid user ID")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						user, err := r.Repository.UpdateUserAccountInfo(ctx, db.UpdateUserAccountInfoParams{
 | 
				
			||||||
 | 
							Bio: input.Bio, FullName: input.Name, Initials: input.Initials, Email: input.Email, UserID: userID,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						return &UpdateUserInfoPayload{User: &user}, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *notificationResolver) ID(ctx context.Context, obj *db.Notification) (uuid.UUID, error) {
 | 
					func (r *notificationResolver) ID(ctx context.Context, obj *db.Notification) (uuid.UUID, error) {
 | 
				
			||||||
	return obj.NotificationID, nil
 | 
						return obj.NotificationID, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,6 +78,7 @@ type UserAccount {
 | 
				
			|||||||
  createdAt: Time!
 | 
					  createdAt: Time!
 | 
				
			||||||
  fullName: String!
 | 
					  fullName: String!
 | 
				
			||||||
  initials: String!
 | 
					  initials: String!
 | 
				
			||||||
 | 
					  bio: String!
 | 
				
			||||||
  role: Role!
 | 
					  role: Role!
 | 
				
			||||||
  username: String!
 | 
					  username: String!
 | 
				
			||||||
  profileIcon: ProfileIcon!
 | 
					  profileIcon: ProfileIcon!
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,19 @@ extend type Mutation {
 | 
				
			|||||||
  updateUserPassword(input: UpdateUserPassword!): UpdateUserPasswordPayload!
 | 
					  updateUserPassword(input: UpdateUserPassword!): UpdateUserPasswordPayload!
 | 
				
			||||||
  updateUserRole(input: UpdateUserRole!):
 | 
					  updateUserRole(input: UpdateUserRole!):
 | 
				
			||||||
   UpdateUserRolePayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG)
 | 
					   UpdateUserRolePayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG)
 | 
				
			||||||
 | 
					  updateUserInfo(input: UpdateUserInfo!):
 | 
				
			||||||
 | 
					    UpdateUserInfoPayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateUserInfoPayload {
 | 
				
			||||||
 | 
					  user: UserAccount!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input UpdateUserInfo {
 | 
				
			||||||
 | 
					  name: String!
 | 
				
			||||||
 | 
					  initials: String!
 | 
				
			||||||
 | 
					  email: String!
 | 
				
			||||||
 | 
					  bio: String!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input UpdateUserPassword {
 | 
					input UpdateUserPassword {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								migrations/0052_add-bio-col-to-user_account.up.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								migrations/0052_add-bio-col-to-user_account.up.sql
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					ALTER TABLE user_account ADD COLUMN bio text NOT NULL DEFAULT '';
 | 
				
			||||||
		Reference in New Issue
	
	Block a user