index.tsx 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { memo } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { useResponsive } from '@/hooks/useResponsive';
  4. import OrderSummary from './components/OrderSummary';
  5. import PayMethodCard from './components/PayMethodCard';
  6. import PlanCard from './components/PlanCard';
  7. import UserInfo from './components/UserInfo';
  8. import { useAction } from './useAction';
  9. import { useService } from './useService';
  10. const Pricing = memo(() => {
  11. const { t } = useTranslation();
  12. const { isMobile } = useResponsive();
  13. const { selectedPlanId, handlePlanClick, selectedPayMethod, handlePayMethodClick } =
  14. useAction();
  15. const { plans, payMethods } = useService();
  16. const selectedPlan = plans.find((plan) => plan.id === selectedPlanId) || null;
  17. return (
  18. <div className="flex items-start justify-center">
  19. <div className={`max-w-[1440px] w-full ${isMobile ? 'px-0' : 'px-[30px]'}`}>
  20. <div
  21. className={`bg-[#0F1116] px-5 sm:px-5 lg:px-[100px] py-[30px] pb-[100px] flex flex-col ${isMobile ? 'gap-5 mt-0' : 'gap-10 my-[50px] rounded-[12px]'}`}
  22. >
  23. <span
  24. className={`text-white font-semibold leading-[1.43] text-center uppercase ${isMobile ? 'text-[22px]' : 'text-[35px]'}`}
  25. >
  26. {t('pages.pricing.title')}
  27. </span>
  28. <UserInfo />
  29. <div className="flex flex-col gap-5">
  30. <span
  31. className={`text-white font-semibold leading-[1.43] ${isMobile ? 'text-[16px]' : 'text-[22px]'}`}
  32. >
  33. {t('pages.pricing.selecPlan')}
  34. </span>
  35. <div
  36. className={`flex ${
  37. isMobile ? 'flex-col-c gap-5' : 'flex-row-c justify-center gap-8'
  38. }`}
  39. >
  40. {plans.map((plan) => (
  41. <PlanCard
  42. key={plan.id}
  43. id={plan.id}
  44. title={plan.title}
  45. subTitle={plan.subTitle}
  46. introduce={plan.introduce}
  47. tag={plan.tag}
  48. tagType={plan.tagType}
  49. isSelected={selectedPlanId === plan.id}
  50. onClick={() => handlePlanClick(plan.id)}
  51. />
  52. ))}
  53. </div>
  54. </div>
  55. <div className="flex flex-col gap-5">
  56. <span
  57. className={`text-white font-semibold leading-[1.43] ${isMobile ? 'text-[16px]' : 'text-[22px]'}`}
  58. >
  59. {t('pages.pricing.selectPayMethod')}
  60. </span>
  61. <div
  62. className={
  63. isMobile
  64. ? 'flex-col-c gap-5'
  65. : 'flex flex-wrap justify-start gap-x-8 gap-y-4 [&>*]:flex-[0_1_calc(50%-1rem)]'
  66. }
  67. >
  68. {payMethods.map((payMethod) => (
  69. <PayMethodCard
  70. key={payMethod}
  71. payMethodType={payMethod}
  72. isSelected={selectedPayMethod === payMethod}
  73. onClick={() => handlePayMethodClick(payMethod)}
  74. />
  75. ))}
  76. </div>
  77. </div>
  78. <OrderSummary selectedPlan={selectedPlan} />
  79. </div>
  80. </div>
  81. </div>
  82. );
  83. });
  84. Pricing.displayName = 'Pricing';
  85. export default Pricing;