Skip to content

Commit

Permalink
feat(storefront): ✨ added update profile options
Browse files Browse the repository at this point in the history
  • Loading branch information
sahrohit committed Sep 11, 2023
1 parent be7c860 commit 4a8c883
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 3 deletions.
87 changes: 87 additions & 0 deletions apps/admin/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,55 @@ export type FieldError = {
message: Scalars["String"];
};

export type Issue = {
__typename?: "Issue";
category: IssueCategory;
categoryId: Scalars["Int"];
comments?: Maybe<Array<IssueComment>>;
completed_at?: Maybe<Scalars["String"]>;
content: Scalars["String"];
created_at: Scalars["String"];
html?: Maybe<Scalars["String"]>;
id: Scalars["Int"];
status: Scalars["String"];
subject: Scalars["String"];
updated_at: Scalars["String"];
user: User;
userId: Scalars["Float"];
};

export type IssueCategory = {
__typename?: "IssueCategory";
created_at: Scalars["String"];
desc: Scalars["String"];
id: Scalars["Int"];
identifier: Scalars["String"];
issues?: Maybe<Array<Issue>>;
name: Scalars["String"];
updated_at: Scalars["String"];
};

export type IssueComment = {
__typename?: "IssueComment";
completed_at?: Maybe<Scalars["String"]>;
content: Scalars["String"];
created_at: Scalars["String"];
html?: Maybe<Scalars["String"]>;
id: Scalars["Int"];
issue: Issue;
issueId: Scalars["Int"];
updated_at: Scalars["String"];
user: User;
userId: Scalars["Float"];
};

export type IssueInput = {
categoryId: Scalars["Float"];
content: Scalars["String"];
html: Scalars["String"];
subject: Scalars["String"];
};

export type Mutation = {
__typename?: "Mutation";
addAddress: Address;
Expand All @@ -134,6 +183,8 @@ export type Mutation = {
addToFavourite: Favourite;
changePassword: UserResponse;
clearCart: Scalars["Boolean"];
createComment: IssueComment;
createIssue: Issue;
createOrder: OrderDetail;
createPayment: CreatePaymentResponse;
deleteAddress: Scalars["Boolean"];
Expand All @@ -148,13 +199,16 @@ export type Mutation = {
register: UserResponse;
removeFromFavourite: Scalars["Boolean"];
resendVerificationEmail: Scalars["Boolean"];
resolveByCustomer: Scalars["Boolean"];
updateAddress: Address;
updateCart: Cart;
updateCategory: ProductCategory;
updateDiscount?: Maybe<DiscountResponse>;
updateIssue: Issue;
updateLanguagePreference: Scalars["Boolean"];
updateMarketingPreference: Scalars["Boolean"];
updatePassword: UserResponse;
updateProfile: User;
updateReview?: Maybe<ProductReview>;
updateStatus: OrderDetail;
verifyEmail: Scalars["Boolean"];
Expand Down Expand Up @@ -196,6 +250,15 @@ export type MutationChangePasswordArgs = {
token: Scalars["String"];
};

export type MutationCreateCommentArgs = {
content: Scalars["String"];
issueId: Scalars["Int"];
};

export type MutationCreateIssueArgs = {
input: IssueInput;
};

export type MutationCreateOrderArgs = {
options: CreateOrderInput;
};
Expand Down Expand Up @@ -252,6 +315,10 @@ export type MutationResendVerificationEmailArgs = {
email: Scalars["String"];
};

export type MutationResolveByCustomerArgs = {
issueId: Scalars["Int"];
};

export type MutationUpdateAddressArgs = {
id: Scalars["Int"];
input: AddressInput;
Expand All @@ -271,6 +338,11 @@ export type MutationUpdateDiscountArgs = {
options: UpdateDiscountInput;
};

export type MutationUpdateIssueArgs = {
id: Scalars["Int"];
input: IssueInput;
};

export type MutationUpdateLanguagePreferenceArgs = {
currency: Scalars["String"];
language: Scalars["String"];
Expand All @@ -287,6 +359,12 @@ export type MutationUpdatePasswordArgs = {
newPassword: Scalars["String"];
};

export type MutationUpdateProfileArgs = {
first_name: Scalars["String"];
imageUrl: Scalars["String"];
last_name: Scalars["String"];
};

export type MutationUpdateReviewArgs = {
desc: Scalars["String"];
isAnonymous: Scalars["Boolean"];
Expand Down Expand Up @@ -484,6 +562,9 @@ export type Query = {
favouritesWithProduct: Array<Favourite>;
fetchCartItems?: Maybe<Array<Cart>>;
hello: Scalars["String"];
issueCategories: Array<IssueCategory>;
issues: Array<Issue>;
issuesWithComments: Issue;
me?: Maybe<User>;
meWithAccount?: Maybe<User>;
orderById?: Maybe<OrderDetail>;
Expand All @@ -506,6 +587,10 @@ export type QueryAllReviewsArgs = {
productId: Scalars["Int"];
};

export type QueryIssuesWithCommentsArgs = {
issueId: Scalars["Int"];
};

export type QueryOrderByIdArgs = {
orderId: Scalars["String"];
};
Expand Down Expand Up @@ -594,6 +679,7 @@ export type User = {
marketing_product_news: Scalars["Boolean"];
phone_number?: Maybe<Scalars["String"]>;
phone_number_verified: Scalars["Boolean"];
role: UserRole;
roleId: Scalars["Float"];
updated_at: Scalars["String"];
};
Expand All @@ -610,6 +696,7 @@ export type UserRole = {
id: Scalars["Int"];
name: Scalars["String"];
updated_at: Scalars["String"];
users: Array<User>;
};

export type Variant = {
Expand Down
38 changes: 38 additions & 0 deletions apps/api/src/migration/1694454773982-Init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class Init1694454773982 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
INSERT INTO public.user_role (id, name) VALUES (1, 'CLIENT');
INSERT INTO public.user_role (id, name) VALUES (2, 'DELIVERY');
INSERT INTO public.user_role (id, name) VALUES (3, 'STAFF');
INSERT INTO public.user_role (id, name) VALUES (4, 'MANAGER');
INSERT INTO public.user_role (id, name) VALUES (5, 'ADMIN');
INSERT INTO public.shipping_method (name, price, dispatch_in) VALUES ( 'Standard Delivery', 8000, 96 );
INSERT INTO public.shipping_method (name, price, dispatch_in) VALUES ( 'Express Delivery', 20000, 24);
INSERT INTO public.issue_category (name, identifier, "desc")
VALUES
('Order and Checkout Issues', 'order-and-checkout-issues', 'Problems related to the ordering and checkout process.'),
('Product and Inventory Problems', 'product-and-inventory-problems', 'Issues concerning product availability, listings, and inventory management.'),
('Security and Privacy Concerns', 'security-and-privacy-concerns', 'Concerns about data security, privacy, and unauthorized access.'),
('Delivery and Shipping Issues', 'delivery-and-shipping-issues', 'Problems with product delivery, shipping delays, and lost shipments.'),
('Customer Account and Login Problems', 'customer-account-and-login-problems', 'Issues related to customer accounts, logins, and profile management.'),
('Returns, Refunds, and Exchanges', 'returns-refunds-and-exchanges', 'Matters concerning product returns, refunds, and exchange requests.'),
('Customer Support and Communication', 'customer-support-and-communication', 'Problems with customer support, response times, and communication.'),
('Discounts, Coupons, and Promotions', 'discounts-coupons-and-promotions', 'Issues related to discounts, coupon codes, and promotional offers.'),
('Product Reviews and Ratings', 'product-reviews-and-ratings', 'Concerns about product reviews, ratings, and feedback management.'),
('Technical Account Management', 'technical-account-management', 'Issues related to account suspension, recovery, or subscription management.'),
('Website Accessibility and Usability', 'website-accessibility-and-usability', 'Accessibility and usability issues for all users, including those with disabilities.'),
('Performance and Loading Speed', 'performance-and-loading-speed', 'Problems with website performance, loading times, and optimization.'),
('Analytics and Reporting', 'analytics-and-reporting', 'Issues with data analytics, reporting, and data privacy.'),
('Feedback and Suggestions', 'feedback-and-suggestions', 'General feedback and suggestions for improving the ecommerce platform.'),
('Legal and Compliance Matters', 'legal-and-compliance-matters', 'Concerns regarding legal compliance, terms of service, and data protection.'),
('Third-Party Integrations and Plugins', 'third-party-integrations-and-plugins', 'Issues with third-party integrations and plugin functionality.'),
('Account Billing and Payments', 'account-billing-and-payments', 'Billing disputes, invoices, and payment-related problems.');
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {}
}
26 changes: 26 additions & 0 deletions apps/api/src/resolvers/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,32 @@ export class UserResolver {
});
}

@Mutation(() => User)
@UseMiddleware(isVerified)
async updateProfile(
@Arg("imageUrl") imageUrl: string,
@Arg("first_name") first_name: string,
@Arg("last_name") last_name: string,
@Ctx() { req }: MyContext
): Promise<User> {
await User.update(
{
id: req.session.userId,
},
{
imageUrl,
first_name,
last_name,
}
);

return User.findOneOrFail({
where: {
id: req.session.userId,
},
});
}

@Mutation(() => UserResponse)
async register(
@Arg("options") options: RegisterInput,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,19 @@ import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as Yup from "yup";
import { HiCloudUpload } from "react-icons/hi";
import { useUpdateProfileMutation } from "@/generated/graphql";
import InputField from "@/components/ui/InputField";

type ProfileFormValues = {
first_name: string;
last_name: string;
imageUrl: string;
};

const ProfileFormSchema = Yup.object({
first_name: Yup.string().required("Required"),
last_name: Yup.string().required("Required"),
imageUrl: Yup.string().required("Required"),
});

interface ProfileFormProps {
Expand All @@ -37,6 +40,7 @@ const ProfileForm = ({
imageUrl,
onSubmissionSuccess: closeModal,
}: ProfileFormProps) => {
const toast = useToast();
const {
register,
handleSubmit,
Expand All @@ -45,16 +49,41 @@ const ProfileForm = ({
defaultValues: {
first_name,
last_name,
imageUrl,
},
resolver: yupResolver(ProfileFormSchema),
});
const toast = useToast();

const [updateProfileMutation] = useUpdateProfileMutation({
refetchQueries: ["Me"],
onCompleted: () => {
toast({
title: "Successfully Updated",
description: `Profile Updated`,
status: "success",
duration: 5000,
isClosable: true,
});
},
onError: (error) => {
toast({
title: "Profile Update Failed",
description: error.message,
status: "error",
duration: 5000,
isClosable: true,
});
},
});

return (
<form
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onSubmit={handleSubmit(async (values) => {
if (closeModal) {
const res = await updateProfileMutation({
variables: values,
});

if (closeModal && res.data?.updateProfile.id) {
closeModal();
}
})}
Expand Down
Loading

2 comments on commit 4a8c883

@vercel
Copy link

@vercel vercel bot commented on 4a8c883 Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

ecommerce-admin-client – ./apps/admin

ecommerce-admin-client.vercel.app
ecommerce-admin-client-sahrohit.vercel.app
ecommerce-admin-client-git-main-sahrohit.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 4a8c883 Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.