diff --git a/component_factory/package.json b/component_factory/package.json index 49e60ff..19ac513 100755 --- a/component_factory/package.json +++ b/component_factory/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "antd": "^5.26.7", + "antd": "^5.27.0", "formik": "^2.4.6", "next": "15.4.5", "react": "19.1.0", @@ -24,6 +24,6 @@ "@types/react": "^19", "@types/react-dom": "^19", "tailwindcss": "^4", - "typescript": "^5" + "typescript": "5.9.2" } } diff --git a/component_factory/public/images.jpeg b/component_factory/public/images.jpeg new file mode 100644 index 0000000..31bc921 Binary files /dev/null and b/component_factory/public/images.jpeg differ diff --git a/component_factory/src/app/css/SpecialOfferModal.scss b/component_factory/src/app/css/SpecialOfferModal.scss new file mode 100644 index 0000000..d66df08 --- /dev/null +++ b/component_factory/src/app/css/SpecialOfferModal.scss @@ -0,0 +1,119 @@ +/** SPECIAL OFFER MODAL **/ +.special-offer-modal-header { + background: linear-gradient(var(--ant-success-color), var(--ant-success-color)), var(--ant-primary-color); + border-bottom: 1px solid hsla(0, 0%, 100%, .1); + border-radius: 16px 16px 0 0; +} + +.special-offer-modal .close-icon { + cursor: pointer; + position: absolute; + right: 20px; + top: 20px; +} + +.special-offer-modal-header-left { + position: relative; +} + +.image-skeleton { + display: flex; + align-items: center; + justify-content: center; +} + +.image-skeleton { + overflow: hidden; + position: relative; +} + +.special-offer-modal-header .image-skeleton { + border-radius: 8px !important; + overflow: hidden; +} + +img { + vertical-align: middle; + border-style: none; +} + +.image-skeleton__image { + width: 100%; + height: 100%; + opacity: 0; + -o-object-fit: cover; + object-fit: cover; + border-radius: inherit; + display: inline-block; +} + +.image-skeleton img { + -o-object-fit: cover; + object-fit: cover; +} + +.image-skeleton__image.original { + position: absolute; + transition: opacity .3s ease-in-out; +} + +.image-skeleton__image.isLoaded { + opacity: 1; +} + + +.special-offer-modal-content-wrapper { + border-radius: 0 0 16px 16px; + overflow: hidden; +} + +.special-offer-modal-content { + background-color: #fff; + max-height: calc(100vh - 160px - 160px); + overflow: auto; + border-radius: 0 0 16px 16px; +} + +.cursor-pointer { + cursor: pointer !important; +} + +.special-offer-modal-copy-btn { + justify-content: space-between; + border: 1px solid #e5e5e5; + border-radius: 8px; +} + +.special-offer-modal-copy-btn-text { + width: calc(100% - 80px); +} + +.copy-text { + font-size: 14px; + line-height: 22px; + color: #257ffc; +} + +@media(max-width: 480px) { + .special-offer-modal { + max-width:calc(100vw - 48px) !important; + margin: 0 auto !important; + } + + .special-offer-modal .close-icon { + top: 8px; + right: 8px; + } + + .special-offer-modal-content { + max-height: calc(100vh - 160px - 200px); + } + + .special-offer-modal-btn-wrapper { + flex-direction: column-reverse; + } + + .special-offer-modal-btn-wrapper .ant-btn { + height: 44px !important; + } +} \ No newline at end of file diff --git a/component_factory/src/app/css/base/button.scss b/component_factory/src/app/css/base/button.scss index 549bfe7..673ae25 100644 --- a/component_factory/src/app/css/base/button.scss +++ b/component_factory/src/app/css/base/button.scss @@ -48,4 +48,122 @@ color: #fff; } +} + + +/** SPECIAL OFFER MODAL **/ +.special-offer-modal +{ + button.ant-btn { + line-height: 1.5715; + position: relative; + display: inline-block; + font-weight: 400; + white-space: nowrap; + text-align: center; + background-image: none; + box-shadow: 0 2px 0 rgba(0, 0, 0, .015); + cursor: pointer; + transition: all .3s cubic-bezier(.645,.045,.355,1); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + touch-action: manipulation; + height: 32px; + padding: 4px 15px; + font-size: 14px; + border-radius: 0; + color: #121212; + border: 1px solid #e9e9eb; + background: #fff; + } + + button.ant-btn-primary { + border: none; + color: #121212; + background: #121212; + font-weight: 700; + line-height: 24px; + border-radius: 123px; + text-transform: uppercase; + letter-spacing: 1px; + } + + button.ant-btn:focus, button.ant-btn:hover { + color: #121212 !important; + border: 2px solid #e0e0e0 !important; + background-color: #e0e0e0 !important; + } + + button.ant-btn-primary:focus, button.ant-btn-primary:hover { + border: none !important; + background: rgba(18, 18, 18, .8) !important; + } + + button.ant-btn.ant-btn-xl { + height: 52px; + border-radius: 123px; + min-width: 160px; + } + + button.ant-btn-uppercase>span { + text-transform: uppercase; + } + + button.ant-btn-primary .ant-typography, button.ant-btn-primary span { + color: #fff; + } + + .ant-btn, .ant-btn:active, .ant-btn:focus { + outline: 0; + } + + button.ant-btn { + min-height: 32px; + box-shadow: none !important; + text-shadow: none; + height: 48px; + border-radius: 123px; + } + + .special-offer-modal-btn-wrapper .ant-btn { + border-radius: 123px; + font-size: 16px; + line-height: 24px; + letter-spacing: 1px; + font-weight: 700; + } + + .visit-store-btn { + background: #121212 !important; + border: none !important; + margin-left: 24px; + } + + .visit-store-btn span { + color: #fff !important; + } + + .ant-btn>span { + display: inline-block; + } + + .w__160 { + width: 160px; + } + + @media (max-width: 480px) { + .visit-store-btn { + width: 100% !important; + margin-bottom: 16px !important; + margin-left: 0 !important; + } + + .cancel-btn { + width: 100% !important; + margin-bottom: 16px !important; + margin-left: 0 !important; + } + } } \ No newline at end of file diff --git a/component_factory/src/app/css/base/modal.scss b/component_factory/src/app/css/base/modal.scss index 8165228..0767b75 100644 --- a/component_factory/src/app/css/base/modal.scss +++ b/component_factory/src/app/css/base/modal.scss @@ -39,3 +39,24 @@ } } + +.special-offer-modal { + + .ant-modal-content { + overflow: visible; + border-radius: 16px !important; + background-color: transparent; + padding: 0 !important; + } + + .ant-modal-body { + padding: 0; + } + + .modal__header { + background: linear-gradient(var(--ant-success-color), var(--ant-success-color)), var(--ant-primary-color); + border-bottom: 1px solid hsla(0, 0%, 100%, .1); + border-radius: 16px 16px 0 0; + } + +} diff --git a/component_factory/src/app/css/base/spacing.scss b/component_factory/src/app/css/base/spacing.scss index be6a597..c9cf3e3 100644 --- a/component_factory/src/app/css/base/spacing.scss +++ b/component_factory/src/app/css/base/spacing.scss @@ -30,3 +30,65 @@ } +/** SPECIAL OFFER MODAL **/ +.special-offer-modal { + + .ant-row { + flex-flow: row wrap; + } + + .ant-row, .ant-row:after, .ant-row:before { + display: flex; + } + + .align__items--center { + align-items: center; + } + + .position--relative { + position: relative; + } + + .p--16 { + padding: 16px !important; + } + + .p__l--16 { + padding-left: 16px !important; + } + + .p__x--16 { + padding-left: 16px !important; + padding-right: 16px !important; + } + + .p__y--16 { + padding-top: 16px !important; + padding-bottom: 16px !important; + } + + .m__t--16 { + margin-top: 16px !important; + } + + .m__b--4 { + margin-bottom: 4px !important; + } + + .p--12 { + padding: 12px !important; + } + + .d--flex, .d--flex--row { + display: flex !important; + } + + .m__t--24 { + margin-top: 24px !important; + } + + .justify__content--end { + justify-content: flex-end; + } + +} diff --git a/component_factory/src/app/css/base/text.scss b/component_factory/src/app/css/base/text.scss index f4e7647..aff4ca4 100644 --- a/component_factory/src/app/css/base/text.scss +++ b/component_factory/src/app/css/base/text.scss @@ -34,3 +34,100 @@ color: #414141 !important; } } + + +/** FRONT CLIENT MODAL: SPECIAL OFFER MODAL **/ +.special-offer-modal { + + .text__align--center { + text-align: center !important; + } + + .text--semibold18.ant-typography { + font-weight: 600 !important; + font-size: 18px !important; + line-height: 28px; + } + + .text--regular14.ant-typography { + font-weight: 400 !important; + font-size: 14px !important; + line-height: 20px; + } + + .text--gray4, .text--gray4.ant-typography, .text--grey4, .text--grey4.ant-typography { + color: #636363 !important; + } + + .leading-22 { + line-height: 22px !important; + } + + .text--tundola, .text--tundola.ant-typography { + color: #414141 !important; + } + + .ant-typography { + color: #121212; + overflow-wrap: break-word; + } + + .ant-typography-ellipsis-multiple-line { + display: -webkit-box; + overflow: hidden; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + } + + .text { + font-weight: 400; + font-size: 14px; + line-height: 20px; + color: #020025; + } + + .ant-typography p, div.ant-typography { + margin-bottom: 1em; + } + + .text--semibold14.ant-typography { + font-weight: 600 !important; + font-size: 14px !important; + line-height: 22px; + } + + .text--regular14.ant-typography { + font-weight: 400 !important; + font-size: 14px !important; + line-height: 20px; + } + + .ant-typography p, .ant-typography.ant-typography-ellipsis, div.ant-typography { + margin-bottom: 0; + } + + .special-offer-modal-header .ant-typography { + color: var(--ant-info-color) !important; + } + + .text--default, .text--default.ant-typography { + color: #121212 !important; + } + + .opacity--06 { + opacity: .6; + } + + .text--regular12.ant-typography { + font-weight: 400 !important; + font-size: 12px !important; + line-height: 16px; + } + + .text--semibold16.ant-typography { + font-weight: 600 !important; + font-size: 16px !important; + line-height: 24px; + } + +} diff --git a/component_factory/src/app/page.tsx b/component_factory/src/app/page.tsx index 8a10b92..8869891 100755 --- a/component_factory/src/app/page.tsx +++ b/component_factory/src/app/page.tsx @@ -9,7 +9,7 @@ export default function Page() { <>
Flat Interface Home Page
-1: Simple Modal
+1: Simple Modal
> ); } diff --git a/component_factory/src/app/simple_modal/page.tsx b/component_factory/src/app/simple_modal/page.tsx index a24251c..8a02eea 100644 --- a/component_factory/src/app/simple_modal/page.tsx +++ b/component_factory/src/app/simple_modal/page.tsx @@ -5,7 +5,7 @@ import React, { useRef, useState, useEffect, useLayoutEffect } from "react"; import { Upload } from "antd"; import { Col, Row } from "antd/lib/grid"; -import "../css/base/App.scss" +import "../css/App.scss" import "../css/base/spacing.scss" import "../css/base/modal.scss" import "../css/base/tabs.scss" diff --git a/component_factory/src/app/special_offer_modal/page.tsx b/component_factory/src/app/special_offer_modal/page.tsx new file mode 100644 index 0000000..7ffd85e --- /dev/null +++ b/component_factory/src/app/special_offer_modal/page.tsx @@ -0,0 +1,169 @@ +"use client"; + +import React, { useState } from "react"; + +import { Col, Row } from "antd/lib/grid"; + +import "../css/App.scss" +import "../css/base/spacing.scss" +import "../css/base/modal.scss" +import "../css/base/tabs.scss" +import "../css/base/text.scss" +import "../css/base/display.scss" +import "../css/base/form.scss" +import "../css/base/button.scss" + +import "../css/SpecialOfferModal.scss"; +import "../css/onboardingFlow.scss" +import "../css/LinkEditorModal.scss"; +import "../css/ProductEditorModal.scss"; +import "../css/ModuleOndemandVideo.scss"; +import "../css/ModuleShopify.scss" + + +import { Field, Form, Formik } from "formik"; +import * as yup from "yup"; +import Button from "antd/lib/button"; + + +import { Text } from "@/components/Typography/Text"; +import { AntInput, FieldType } from "@/components/Form/FormItem"; +import Modal from "@/components/Modal/Modal"; + +const validateSpecialOfferSchema = yup.object().shape({ + specialOffer: yup.object().shape({ + title: yup + .string() + .required("Please add the offer information") + .max(50, "Offer not more than 50 characters"), + storeUrl: yup + .string() + .required("Please enter the URL") + .url("Please enter a valid URL"), + }), +}); + +export default function Page() { + const [isModalOpen, setIsModalOpen] = useState(false); + + const initialValues = { + specialOffer: { + title: "offer", + storeUrl: "https://google.com", + couponCode: "5", + }, + }; + + const handleSubmit = (values: typeof initialValues) => { + console.log("Form submit", values); + }; + + return ( + <> + + +