SubscribeNewsletter.tsx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. "use client";
  2. import Link from "next/link";
  3. import { useForm, type FieldErrors } from "react-hook-form";
  4. import { SUBSCRIBE_TO_NEWSLETTER } from "@/graphql/theme/mutations";
  5. import { useApolloClient } from "@apollo/client/react";
  6. import { useCustomToast } from "@utils/hooks/useToast";
  7. import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
  8. import { EMAIL_REGEX } from "@utils/constants";
  9. type FormValues = {
  10. email: string;
  11. isAgree: boolean;
  12. };
  13. export default function SubscribeNewsletter() {
  14. const apolloClient = useApolloClient();
  15. const { showToast } = useCustomToast();
  16. const {
  17. register,
  18. handleSubmit,
  19. formState: { errors }
  20. } = useForm<FormValues>({
  21. mode: "onChange",
  22. reValidateMode: "onChange",
  23. defaultValues: {
  24. email: '',
  25. isAgree: true
  26. }
  27. });
  28. const onSubmit = async (data: FormValues) => {
  29. overlayLoading.start();
  30. apolloClient.mutate({
  31. mutation: SUBSCRIBE_TO_NEWSLETTER,
  32. variables: {
  33. input: {
  34. customerEmail: data.email
  35. }
  36. }
  37. }).then((res) => {
  38. overlayLoading.stop();
  39. const resData = res.data?.createNewsletter?.newsletter;
  40. let success = true;
  41. let msg = "";
  42. if(resData) {
  43. success = resData.success;
  44. msg = resData.message;
  45. } else {
  46. success = false;
  47. msg = 'Fail to subscribe!';
  48. }
  49. if(success) {
  50. showToast(msg, 'success');
  51. } else {
  52. showToast(msg, 'danger');
  53. }
  54. }).catch((err) => {
  55. overlayLoading.stop();
  56. showToast(err.message, "danger");
  57. });
  58. };
  59. const onInvalid = (errors: FieldErrors<FormValues>) => {
  60. const msg = errors.isAgree?.message
  61. if (msg) {
  62. showToast(msg,"warning");
  63. }
  64. };
  65. return (<>
  66. <div className="text-ly-16 text-[#FFDBA3] font-bold">Get the latest News Posted</div>
  67. <form className="w-full mt-6" onSubmit={handleSubmit(onSubmit,onInvalid)}>
  68. <div className="w-full h-11 bg-white">
  69. <input type="text" className="block w-full h-full border-1 px-3 text-ly-14 placeholder:text-[#d3d3d3]"
  70. placeholder="Email Address"
  71. {...register('email', {
  72. required: "Email is required",
  73. pattern: {
  74. value: EMAIL_REGEX,
  75. message: "Enter a valid email",
  76. },
  77. })}
  78. />
  79. </div>
  80. {errors.email && <p className="text-red-500 text-ly-12">{errors.email.message}</p>}
  81. <button className="flex justify-center items-center mt-4 w-full h-12 rounded-lg bg-white text-ly-16 text-ly-middlegreen font-bold" type="submit">
  82. Subscribe Now
  83. </button>
  84. <label className="w-full mt-3 flex items-start" htmlFor="footer_subscribe_is_agree">
  85. <div className="group block relative w-4 h-4 mt-1 mr-2">
  86. <input type="checkbox" className="absolute w-full h-full top-0 left-0 opacity-0" id="footer_subscribe_is_agree"
  87. {...register("isAgree", {
  88. required: "Please agree to the Terms & Conditions and Privacy Policy."
  89. })}
  90. />
  91. <svg className="icon-check hidden group-has-[:checked]:block" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" width="17" height="17" viewBox="0 0 17 17" fill="none">
  92. <rect x="0.5" y="0.5" width="16" height="16" rx="1" fill="#FFFFFF" ></rect>
  93. <path fill="rgba(0, 0, 0, 1)" d="M1.5 0L15.5 0C16.3284 0 17 0.671573 17 1.5L17 15.5C17 16.3284 16.3284 17 15.5 17L1.5 17C0.671573 17 0 16.3284 0 15.5L0 1.5C0 0.671573 0.671573 0 1.5 0ZM1.5 1C1.22386 1 1 1.22386 1 1.5L1 15.5C1 15.7761 1.22386 16 1.5 16L15.5 16C15.7761 16 16 15.7761 16 15.5L16 1.5C16 1.22386 15.7761 1 15.5 1L1.5 1Z"></path>
  94. <path d="M13.78 5.84263L7.78033 12.1324C7.48744 12.4394 7.01256 12.4394 6.71967 12.1324L3.71967 8.9873L3.71953 8.98715C3.58389 8.84488 3.5 8.64837 3.5 8.43132C3.5 8.21427 3.58389 8.01777 3.71953 7.8755L3.71967 7.87535C3.75449 7.83885 3.79236 7.80626 3.8333 7.77758C3.87424 7.7489 3.91745 7.72469 3.96294 7.70493C4.00843 7.68517 4.05532 7.67026 4.10361 7.66019C4.1519 7.65011 4.20067 7.64507 4.2499 7.64506C4.29914 7.64505 4.34791 7.65008 4.3962 7.66014C4.44449 7.6702 4.49139 7.6851 4.53688 7.70485C4.58237 7.7246 4.62559 7.7488 4.66654 7.77747C4.70748 7.80613 4.74537 7.83871 4.78019 7.8752L4.78033 7.87535L7.25 10.4644L12.7193 4.73068L12.7197 4.73029C12.79 4.65657 12.8711 4.59975 12.963 4.55985C13.0549 4.51995 13.1505 4.5 13.25 4.5C13.4571 4.5 13.6446 4.58801 13.7803 4.73029C13.916 4.87258 14 5.06914 14 5.28626C14 5.50339 13.916 5.69995 13.7803 5.84224L13.78 5.84263Z" fill="#000000" ></path>
  95. </svg>
  96. <svg className="icon-uncheck block group-has-[:checked]:hidden" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" width="17" height="17" viewBox="0 0 17 17" fill="none">
  97. <rect x="0.5" y="0.5" width="16" height="16" rx="1" fill="#FFFFFF" ></rect>
  98. <path fill="rgba(0, 0, 0, 1)" d="M1.5 0L15.5 0C16.3284 0 17 0.671573 17 1.5L17 15.5C17 16.3284 16.3284 17 15.5 17L1.5 17C0.671573 17 0 16.3284 0 15.5L0 1.5C0 0.671573 0.671573 0 1.5 0ZM1.5 1C1.22386 1 1 1.22386 1 1.5L1 15.5C1 15.7761 1.22386 16 1.5 16L15.5 16C15.7761 16 16 15.7761 16 15.5L16 1.5C16 1.22386 15.7761 1 15.5 1L1.5 1Z"></path>
  99. </svg>
  100. </div>
  101. <p className="text-ly-12 leading-5 text-white">
  102. I agree to the
  103. <Link className="underline" href="/privacy-policy">Privacy Policy</Link>
  104. and
  105. <Link className="underline" href="/terms-conditions">Terms & Conditions</Link>.
  106. And consent to receive marketing messages via email and phone number. Unsubscribe anytime.
  107. </p>
  108. </label>
  109. </form>
  110. </>);
  111. };