From 945b102d1a1380c0ee0baa8cf1de1ead4ddf56b3 Mon Sep 17 00:00:00 2001 From: TEJAS <98630752+tejaskh3@users.noreply.github.com> Date: Thu, 24 Oct 2024 19:40:01 +0530 Subject: [PATCH 1/3] Dev to Main Sync (#949) * Subscription feature (#936) * feat: add form to collect subscription data * feat: add form to collect subscription data * WIP: add ember-phone-input * feat: add not loggedin and subscribed screen and integreate API * feat: fixing bug * fix: bug to show form even if user is already subscribed * fix: urls * fix: urls * fix: urls * delete: service subscribe test * fix: resolve comments * Update app/components/header.hbs Co-authored-by: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> * fix: comments and remove modal * fix: phone number input * fix: content change * fix: remove card * fix: remove comments * fix:subscribe message --------- Co-authored-by: Vinit khandal <111434418+vinit717@users.noreply.github.com> Co-authored-by: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> * subscription feature fixes (#944) * fix: navbar & css & phone validation * fix: PR comments * feat: add error to in valid input * fix: lint --------- Co-authored-by: Vinit khandal <111434418+vinit717@users.noreply.github.com> Co-authored-by: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> --- app/components/header.hbs | 2 +- app/components/join-section.hbs | 3 + app/constants/regex.js | 2 + app/constants/urls.js | 1 + app/controllers/subscribe.js | 100 ++++++++++++ app/models/user.js | 3 + app/router.js | 1 + app/routes/subscribe.js | 3 + app/styles/app.css | 2 + app/styles/base-modal.module.css | 6 +- app/styles/join-section.module.css | 27 ++++ app/styles/phone-input.module.css | 23 +++ app/styles/subscribe.module.css | 242 +++++++++++++++++++++++++++++ app/templates/subscribe.hbs | 49 ++++++ config/environment.js | 6 + package.json | 1 + yarn.lock | 24 +++ 17 files changed, 493 insertions(+), 2 deletions(-) create mode 100644 app/constants/regex.js create mode 100644 app/controllers/subscribe.js create mode 100644 app/routes/subscribe.js create mode 100644 app/styles/phone-input.module.css create mode 100644 app/styles/subscribe.module.css create mode 100644 app/templates/subscribe.hbs diff --git a/app/components/header.hbs b/app/components/header.hbs index dfd80d93..54224285 100644 --- a/app/components/header.hbs +++ b/app/components/header.hbs @@ -51,7 +51,7 @@ class="nav__element" href={{this.STATUS_URL}} >Status - {{#if @dev}} + {{#if @dev}}
  • {{! TODO - remove query for dev when it goes to production }} + {{else}}
    diff --git a/app/constants/regex.js b/app/constants/regex.js new file mode 100644 index 00000000..59c5b265 --- /dev/null +++ b/app/constants/regex.js @@ -0,0 +1,2 @@ +export const phoneNumberRegex = + /^[+]{1}(?:[0-9\-\\(\\)\\/.]\s?){6,15}[0-9]{1}$/; diff --git a/app/constants/urls.js b/app/constants/urls.js index b65938f2..e4eaf6e0 100644 --- a/app/constants/urls.js +++ b/app/constants/urls.js @@ -99,3 +99,4 @@ export const SOCIALS = { }; export const ANKUSH_TWITTER = 'https://twitter.com/ankushdharkar'; +export const RDS_TWITTER = 'https://x.com/realdevsquad'; diff --git a/app/controllers/subscribe.js b/app/controllers/subscribe.js new file mode 100644 index 00000000..278adef8 --- /dev/null +++ b/app/controllers/subscribe.js @@ -0,0 +1,100 @@ +import Controller from '@ember/controller'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; +import { inject as service } from '@ember/service'; +import { RDS_TWITTER, APPS } from '../constants/urls'; +import { TOAST_OPTIONS } from '../constants/toast-options'; +import { phoneNumberRegex } from '../constants/regex'; + +export default class SubscribeController extends Controller { + @service login; + @tracked isFormOpen = false; + @tracked email = ''; + @tracked phone = ''; + @tracked userData = null; + @tracked isLoading = false; + @tracked showSubscribedMessage = false; + @service toast; + @tracked isPhoneValid = true; + + RDS_TWITTER = RDS_TWITTER; + + constructor() { + super(...arguments); + this.userData = this.login.userData; + } + + get isLoggedIn() { + return this.login.isLoggedIn; + } + + get isSubscribed() { + return this.login.userData.isSubscribed; + } + + get isSubmitDisabled() { + const isPhoneValid = !this.phone || phoneNumberRegex.test(this.phone); + return !this.email || !isPhoneValid; + } + + @action + toggleFormModal() { + this.isFormOpen = !this.isFormOpen; + } + + @action + updateEmail(event) { + this.email = event.target.value; + } + + @action + updatePhone(event) { + this.phone = event.target.value; + this.isPhoneValid = !this.phone || phoneNumberRegex.test(this.phone); + } + + @action + async handleSubmit(event) { + event.preventDefault(); + if (!this.isSubmitDisabled) { + this.isLoading = true; + try { + const url = `${APPS.API_BACKEND}/subscription?dev=true`; + const response = await fetch(url, { + method: 'POST', + body: JSON.stringify({ + email: this.email, + phoneNumber: this.phone, + }), + headers: { + 'Content-Type': 'application/json', + }, + credentials: 'include', + }); + if (!response.ok) { + this.toast.error( + 'Something went wrong. Please try again.', + '', + TOAST_OPTIONS, + ); + } else { + this.login.userData.isSubscribed = true; + this.isFormOpen = false; + this.showSubscribedMessage = true; + this.toast.success('🎉 Thankyou for subscribing!', '', TOAST_OPTIONS); + } + } catch (error) { + console.log(error); + this.toast.error( + `Something went wrong. ${error.message}`, + '', + TOAST_OPTIONS, + ); + } finally { + this.isLoading = false; + } + this.email = ''; + this.phone = ''; + } + } +} diff --git a/app/models/user.js b/app/models/user.js index dbd0f80d..1a1caebb 100644 --- a/app/models/user.js +++ b/app/models/user.js @@ -20,4 +20,7 @@ export default class UserModel extends Model { @attr profileURL; @attr profileStatus; @attr website; + @attr isSubscribed; + @attr phoneNumber; + @attr email; } diff --git a/app/router.js b/app/router.js index 111652e7..a78344ed 100644 --- a/app/router.js +++ b/app/router.js @@ -15,4 +15,5 @@ Router.map(function () { this.route('goto'); this.route('events'); this.route('debug'); + this.route('subscribe'); }); diff --git a/app/routes/subscribe.js b/app/routes/subscribe.js new file mode 100644 index 00000000..b2338e80 --- /dev/null +++ b/app/routes/subscribe.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class SubscribeRoute extends Route {} diff --git a/app/styles/app.css b/app/styles/app.css index 9de6edd7..48c90b21 100644 --- a/app/styles/app.css +++ b/app/styles/app.css @@ -41,6 +41,8 @@ @import url("tooltip.module.css"); @import url("debug.module.css"); @import url("unauthenticated.module.css"); +@import url("subscribe.module.css"); +@import url("phone-input.module.css"); * { margin: 0; diff --git a/app/styles/base-modal.module.css b/app/styles/base-modal.module.css index 74c0e666..f44310f4 100644 --- a/app/styles/base-modal.module.css +++ b/app/styles/base-modal.module.css @@ -9,7 +9,11 @@ } .base-modal--show { - display: block; + display: flex; + align-items: center; + justify-content: center; + background-color: #000000b2; + backdrop-filter: blur(5px); } .base-modal--hide { diff --git a/app/styles/join-section.module.css b/app/styles/join-section.module.css index a63cda06..203185e5 100644 --- a/app/styles/join-section.module.css +++ b/app/styles/join-section.module.css @@ -41,6 +41,13 @@ line-height: 175%; } +.links__container { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; +} + .join__link { display: inline-block; margin-top: 2rem; @@ -54,11 +61,23 @@ padding: 1.25rem 3rem; } +.subscribe__link { + display: flex; + justify-content: center; + align-items: center; + gap: 5px; + padding: 1.125rem 3.75rem; +} + .join__link:hover { background-color: var(--color-pink); transition-duration: 250ms; } +.subscribe__link span { + font-size: 1.125rem; +} + .join__link--new { background-color: var(--color-button-disabled); cursor: not-allowed; @@ -126,6 +145,10 @@ font-size: 1.25rem; padding: 1rem 2.5rem; } + + .subscribe__link span { + font-size: 0.75rem; + } } @media (width <=425px) { @@ -147,4 +170,8 @@ font-size: 1rem; padding: 0.75rem 2rem; } + + .subscribe__link span { + font-size: 0.75rem; + } } diff --git a/app/styles/phone-input.module.css b/app/styles/phone-input.module.css new file mode 100644 index 00000000..1ead37c9 --- /dev/null +++ b/app/styles/phone-input.module.css @@ -0,0 +1,23 @@ +.phone-input { + display: flex; + align-items: center; + margin-bottom: 10px; +} + +.country-code-select { + margin-right: 10px; +} + +.phone-number-input { + flex-grow: 1; +} + +.phone-input select, +.phone-input input[type="tel"] { + width: 100%; + padding: 5px; +} + +button { + padding: 5px 10px; +} diff --git a/app/styles/subscribe.module.css b/app/styles/subscribe.module.css new file mode 100644 index 00000000..b610d4d8 --- /dev/null +++ b/app/styles/subscribe.module.css @@ -0,0 +1,242 @@ +@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"); + +.subscribe__container { + background-color: var(--color-white); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2rem; + text-align: center; + min-height: 76vh; +} + +.subscribe__container h1, +.subscribe__form_container h1 { + font-size: 2rem; + font-weight: 700; + color: #111827; + text-align: center; +} + +.subscribe__container p, +.subscribe__form_container p { + font-family: Inter, sans-serif; + font-size: 1.25rem; + font-weight: 400; + line-height: 1.875rem; + text-align: center; +} + +.notification__text { + font-size: 18px; + color: #dc2626; +} + +.sub__text { + font-size: 16px; + color: #374151; +} + +.notify__btn { + font-size: 16px; + background-color: #1e429f; + color: white; + padding: 0.75rem 1.5rem; + border: none; + border-radius: 8px; + cursor: pointer; + transition: background-color 0.3s ease; + text-align: center; +} + +.notify__btn:hover { + background-color: #1558b0; +} + +.notify__btn a { + display: block; + padding: 12px; + background-color: #1e429f; + color: white; + text-decoration: none; + border-radius: 6px; + font-weight: 600; + transition: background-color 0.3s; +} + +.subscribed__confirmed nav a { + display: block; + padding: 12px; + background-color: #1e429f; + color: white; + text-decoration: none; + border-radius: 6px; + font-weight: 600; + transition: background-color 0.3s; +} + +.notify__btn a:hover, +.notify__btn:hover a { + background-color: #163a7b; +} + +.subscribe__form_container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 5px; +} + +.subscribe__form_container p { + font-family: Inter, sans-serif; + font-size: 20px; + font-weight: 400; + line-height: 30px; + color: #6b7280; +} + +.subscribe__form { + background-color: white; + width: 100%; + max-width: 500px; + position: relative; + box-sizing: border-box; + padding: 30px; + box-shadow: rgb(17 12 46 / 15%) 0 48px 100px 0; + border-radius: 8px; + margin-top: 5rem; +} + +.subscribed__confirmed__close__btn { + position: absolute; + top: 12px; + right: 15px; + padding: 5px; + background: none; + border: none; + cursor: pointer; + font-size: 24px; + line-height: 1; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + transition: background-color 0.3s ease; +} + +.input__group { + margin-bottom: 1.5rem; + display: flex; + flex-direction: column; +} + +.input__group label { + font-family: Inter, sans-serif; + font-size: 16px; + font-weight: 500; + line-height: 24px; + text-align: left; +} + +.input__group__span { + color: #374151; +} + +.input__group input::placeholder { + color: #6b7280; +} + +.input__group input { + padding: 0.75rem; + border: 1px solid #d1d5db; + border-radius: 6px; + font-family: Inter, sans-serif; + font-size: 14px; + font-weight: 400; + line-height: 17.5px; + text-align: left; + color: #000; +} + +.invalid-input { + border-color: #dc2626; + color: red; +} + +.submit__btn { + padding: 1rem; + background-color: #1e429f; + color: white; + border: none; + border-radius: 6px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.subscribe__button { + width: 100%; +} + +.subscribe__button:disabled { + background-color: #dadada; +} + +.login__message { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2rem; + text-align: center; +} + +.login__message h1 { + font-size: 32px; + font-weight: 700; + color: #111827; +} + +.login__message p { + font-family: Inter, sans-serif; + font-size: 20px; + font-weight: 400; + line-height: 30px; + color: #6b7280; +} + +.login__message .sub__text { + font-size: 16px; + color: #374151; + margin-top: 1rem; +} + +.already-subscribed { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1.5rem; + text-align: center; + max-width: 600px; + margin: 0 auto; +} + +.already-subscribed h1 { + font-size: 32px; + font-weight: 700; + color: #1e429f; + text-align: center; +} + +.already-subscribed p { + font-family: Inter, sans-serif; + font-size: 18px; + font-weight: 400; + line-height: 28px; + color: #374151; + text-align: center; +} diff --git a/app/templates/subscribe.hbs b/app/templates/subscribe.hbs new file mode 100644 index 00000000..1eb4eda5 --- /dev/null +++ b/app/templates/subscribe.hbs @@ -0,0 +1,49 @@ +{{page-title 'Subscribe'}} + + diff --git a/config/environment.js b/config/environment.js index f0094847..18dc1fe2 100644 --- a/config/environment.js +++ b/config/environment.js @@ -21,14 +21,20 @@ module.exports = function (environment) { fastboot: { hostWhitelist: [/^localhost:\d+$/, 'dev.realdevsquad.com'], }, + phoneInput: { + lazyLoad: true, + hasPrepend: false, + }, }; if (environment === 'production') { ENV.fastboot.hostWhitelist = ['realdevsquad.com']; + ENV.phoneInput.hasPrepend = true; } if (environment === 'staging') { ENV.fastboot.hostWhitelist = ['beta.realdevsquad.com']; + ENV.phoneInput.hasPrepend = true; } if (environment === 'development') { diff --git a/package.json b/package.json index 88b71842..87edafbc 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "d3-cloud": "1.2.7", "dotenv": "16.0.2", "ember-d3": "0.5.1", + "ember-phone-input": "^10.0.0", "exists-sync": "0.1.0", "fastboot-app-server": "3.3.2" }, diff --git a/yarn.lock b/yarn.lock index a0e258c2..5ee44be1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3110,6 +3110,15 @@ ember-cli-babel "^7.26.11" ember-modifier-manager-polyfill "^1.2.0" +"@ember/render-modifiers@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-2.1.0.tgz#f4fff95a8b5cfbe947ec46644732d511711c5bf9" + integrity sha512-LruhfoDv2itpk0fA0IC76Sxjcnq/7BC6txpQo40hOko8Dn6OxwQfxkPIbZGV0Cz7df+iX+VJrcYzNIvlc3w2EQ== + dependencies: + "@embroider/macros" "^1.0.0" + ember-cli-babel "^7.26.11" + ember-modifier-manager-polyfill "^1.2.0" + "@ember/string@3.1.1": version "3.1.1" resolved "https://registry.yarnpkg.com/@ember/string/-/string-3.1.1.tgz#0a5ac0d1e4925259e41d5c8d55ef616117d47ff0" @@ -9188,6 +9197,16 @@ ember-page-title@8.2.3: "@embroider/addon-shim" "^1.8.7" "@simple-dom/document" "^1.4.0" +ember-phone-input@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ember-phone-input/-/ember-phone-input-10.0.0.tgz#0aaac5e57e3cbd3f20973138d39c77caf5c6b36b" + integrity sha512-kebV05W7Y2+DN+xSwvPWe0ocVI3gK2UlaOjw8G1g5rw1Aoe0ouFI5ecCs+/5YvHRzPZzpASyrC3w63vpgSo9jA== + dependencies: + "@ember/render-modifiers" "^2.1.0" + "@embroider/addon-shim" "^1.8.7" + intl-tel-input "^18.0.0" + rsvp "^4.8.5" + ember-qunit@8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-8.0.2.tgz#a6346136cba785853f176dfa6ed25e3f0a11b7a0" @@ -11376,6 +11395,11 @@ intersection-observer-admin@~0.3.2: resolved "https://registry.yarnpkg.com/intersection-observer-admin/-/intersection-observer-admin-0.3.3.tgz#176a2a08c1cfa9ec3bc74d81cb9ba6483c30e625" integrity sha512-aKMJPw/8cxybcgYTbnwGn87VgSFbSNNqeChRJahD+ai+jtwlCOdIcEvtuBd2BWO9bPuylVgeQVmGGfX2aS1NIg== +intl-tel-input@^18.0.0: + version "18.5.3" + resolved "https://registry.yarnpkg.com/intl-tel-input/-/intl-tel-input-18.5.3.tgz#20b18431cb802d33c118f52e332e218e641ec09b" + integrity sha512-ncFqSpkdGf2YC/FvAiwBH44KAeRG8L7aqDODEpOvMAT3ZpBtvc/WtwaQ/6X4+HKDTlGkobdBjr6P3nAMwO8jtA== + invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" From 27d5a3b6a6ab6c6fc7485f2097d1ff291867f413 Mon Sep 17 00:00:00 2001 From: Lakshay Manchanda <45519620+lakshayman@users.noreply.github.com> Date: Thu, 24 Oct 2024 20:19:48 +0530 Subject: [PATCH 2/3] Revert "Dev to Main Sync (#949)" (#950) This reverts commit 945b102d1a1380c0ee0baa8cf1de1ead4ddf56b3. --- app/components/header.hbs | 2 +- app/components/join-section.hbs | 3 - app/constants/regex.js | 2 - app/constants/urls.js | 1 - app/controllers/subscribe.js | 100 ------------ app/models/user.js | 3 - app/router.js | 1 - app/routes/subscribe.js | 3 - app/styles/app.css | 2 - app/styles/base-modal.module.css | 6 +- app/styles/join-section.module.css | 27 ---- app/styles/phone-input.module.css | 23 --- app/styles/subscribe.module.css | 242 ----------------------------- app/templates/subscribe.hbs | 49 ------ config/environment.js | 6 - package.json | 1 - yarn.lock | 24 --- 17 files changed, 2 insertions(+), 493 deletions(-) delete mode 100644 app/constants/regex.js delete mode 100644 app/controllers/subscribe.js delete mode 100644 app/routes/subscribe.js delete mode 100644 app/styles/phone-input.module.css delete mode 100644 app/styles/subscribe.module.css delete mode 100644 app/templates/subscribe.hbs diff --git a/app/components/header.hbs b/app/components/header.hbs index 54224285..dfd80d93 100644 --- a/app/components/header.hbs +++ b/app/components/header.hbs @@ -51,7 +51,7 @@ class="nav__element" href={{this.STATUS_URL}} >Status
  • - {{#if @dev}} + {{#if @dev}}
  • {{! TODO - remove query for dev when it goes to production }} - {{else}}
    diff --git a/app/constants/regex.js b/app/constants/regex.js deleted file mode 100644 index 59c5b265..00000000 --- a/app/constants/regex.js +++ /dev/null @@ -1,2 +0,0 @@ -export const phoneNumberRegex = - /^[+]{1}(?:[0-9\-\\(\\)\\/.]\s?){6,15}[0-9]{1}$/; diff --git a/app/constants/urls.js b/app/constants/urls.js index e4eaf6e0..b65938f2 100644 --- a/app/constants/urls.js +++ b/app/constants/urls.js @@ -99,4 +99,3 @@ export const SOCIALS = { }; export const ANKUSH_TWITTER = 'https://twitter.com/ankushdharkar'; -export const RDS_TWITTER = 'https://x.com/realdevsquad'; diff --git a/app/controllers/subscribe.js b/app/controllers/subscribe.js deleted file mode 100644 index 278adef8..00000000 --- a/app/controllers/subscribe.js +++ /dev/null @@ -1,100 +0,0 @@ -import Controller from '@ember/controller'; -import { tracked } from '@glimmer/tracking'; -import { action } from '@ember/object'; -import { inject as service } from '@ember/service'; -import { RDS_TWITTER, APPS } from '../constants/urls'; -import { TOAST_OPTIONS } from '../constants/toast-options'; -import { phoneNumberRegex } from '../constants/regex'; - -export default class SubscribeController extends Controller { - @service login; - @tracked isFormOpen = false; - @tracked email = ''; - @tracked phone = ''; - @tracked userData = null; - @tracked isLoading = false; - @tracked showSubscribedMessage = false; - @service toast; - @tracked isPhoneValid = true; - - RDS_TWITTER = RDS_TWITTER; - - constructor() { - super(...arguments); - this.userData = this.login.userData; - } - - get isLoggedIn() { - return this.login.isLoggedIn; - } - - get isSubscribed() { - return this.login.userData.isSubscribed; - } - - get isSubmitDisabled() { - const isPhoneValid = !this.phone || phoneNumberRegex.test(this.phone); - return !this.email || !isPhoneValid; - } - - @action - toggleFormModal() { - this.isFormOpen = !this.isFormOpen; - } - - @action - updateEmail(event) { - this.email = event.target.value; - } - - @action - updatePhone(event) { - this.phone = event.target.value; - this.isPhoneValid = !this.phone || phoneNumberRegex.test(this.phone); - } - - @action - async handleSubmit(event) { - event.preventDefault(); - if (!this.isSubmitDisabled) { - this.isLoading = true; - try { - const url = `${APPS.API_BACKEND}/subscription?dev=true`; - const response = await fetch(url, { - method: 'POST', - body: JSON.stringify({ - email: this.email, - phoneNumber: this.phone, - }), - headers: { - 'Content-Type': 'application/json', - }, - credentials: 'include', - }); - if (!response.ok) { - this.toast.error( - 'Something went wrong. Please try again.', - '', - TOAST_OPTIONS, - ); - } else { - this.login.userData.isSubscribed = true; - this.isFormOpen = false; - this.showSubscribedMessage = true; - this.toast.success('🎉 Thankyou for subscribing!', '', TOAST_OPTIONS); - } - } catch (error) { - console.log(error); - this.toast.error( - `Something went wrong. ${error.message}`, - '', - TOAST_OPTIONS, - ); - } finally { - this.isLoading = false; - } - this.email = ''; - this.phone = ''; - } - } -} diff --git a/app/models/user.js b/app/models/user.js index 1a1caebb..dbd0f80d 100644 --- a/app/models/user.js +++ b/app/models/user.js @@ -20,7 +20,4 @@ export default class UserModel extends Model { @attr profileURL; @attr profileStatus; @attr website; - @attr isSubscribed; - @attr phoneNumber; - @attr email; } diff --git a/app/router.js b/app/router.js index a78344ed..111652e7 100644 --- a/app/router.js +++ b/app/router.js @@ -15,5 +15,4 @@ Router.map(function () { this.route('goto'); this.route('events'); this.route('debug'); - this.route('subscribe'); }); diff --git a/app/routes/subscribe.js b/app/routes/subscribe.js deleted file mode 100644 index b2338e80..00000000 --- a/app/routes/subscribe.js +++ /dev/null @@ -1,3 +0,0 @@ -import Route from '@ember/routing/route'; - -export default class SubscribeRoute extends Route {} diff --git a/app/styles/app.css b/app/styles/app.css index 48c90b21..9de6edd7 100644 --- a/app/styles/app.css +++ b/app/styles/app.css @@ -41,8 +41,6 @@ @import url("tooltip.module.css"); @import url("debug.module.css"); @import url("unauthenticated.module.css"); -@import url("subscribe.module.css"); -@import url("phone-input.module.css"); * { margin: 0; diff --git a/app/styles/base-modal.module.css b/app/styles/base-modal.module.css index f44310f4..74c0e666 100644 --- a/app/styles/base-modal.module.css +++ b/app/styles/base-modal.module.css @@ -9,11 +9,7 @@ } .base-modal--show { - display: flex; - align-items: center; - justify-content: center; - background-color: #000000b2; - backdrop-filter: blur(5px); + display: block; } .base-modal--hide { diff --git a/app/styles/join-section.module.css b/app/styles/join-section.module.css index 203185e5..a63cda06 100644 --- a/app/styles/join-section.module.css +++ b/app/styles/join-section.module.css @@ -41,13 +41,6 @@ line-height: 175%; } -.links__container { - display: flex; - flex-direction: column; - align-items: center; - width: 100%; -} - .join__link { display: inline-block; margin-top: 2rem; @@ -61,23 +54,11 @@ padding: 1.25rem 3rem; } -.subscribe__link { - display: flex; - justify-content: center; - align-items: center; - gap: 5px; - padding: 1.125rem 3.75rem; -} - .join__link:hover { background-color: var(--color-pink); transition-duration: 250ms; } -.subscribe__link span { - font-size: 1.125rem; -} - .join__link--new { background-color: var(--color-button-disabled); cursor: not-allowed; @@ -145,10 +126,6 @@ font-size: 1.25rem; padding: 1rem 2.5rem; } - - .subscribe__link span { - font-size: 0.75rem; - } } @media (width <=425px) { @@ -170,8 +147,4 @@ font-size: 1rem; padding: 0.75rem 2rem; } - - .subscribe__link span { - font-size: 0.75rem; - } } diff --git a/app/styles/phone-input.module.css b/app/styles/phone-input.module.css deleted file mode 100644 index 1ead37c9..00000000 --- a/app/styles/phone-input.module.css +++ /dev/null @@ -1,23 +0,0 @@ -.phone-input { - display: flex; - align-items: center; - margin-bottom: 10px; -} - -.country-code-select { - margin-right: 10px; -} - -.phone-number-input { - flex-grow: 1; -} - -.phone-input select, -.phone-input input[type="tel"] { - width: 100%; - padding: 5px; -} - -button { - padding: 5px 10px; -} diff --git a/app/styles/subscribe.module.css b/app/styles/subscribe.module.css deleted file mode 100644 index b610d4d8..00000000 --- a/app/styles/subscribe.module.css +++ /dev/null @@ -1,242 +0,0 @@ -@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"); - -.subscribe__container { - background-color: var(--color-white); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 2rem; - text-align: center; - min-height: 76vh; -} - -.subscribe__container h1, -.subscribe__form_container h1 { - font-size: 2rem; - font-weight: 700; - color: #111827; - text-align: center; -} - -.subscribe__container p, -.subscribe__form_container p { - font-family: Inter, sans-serif; - font-size: 1.25rem; - font-weight: 400; - line-height: 1.875rem; - text-align: center; -} - -.notification__text { - font-size: 18px; - color: #dc2626; -} - -.sub__text { - font-size: 16px; - color: #374151; -} - -.notify__btn { - font-size: 16px; - background-color: #1e429f; - color: white; - padding: 0.75rem 1.5rem; - border: none; - border-radius: 8px; - cursor: pointer; - transition: background-color 0.3s ease; - text-align: center; -} - -.notify__btn:hover { - background-color: #1558b0; -} - -.notify__btn a { - display: block; - padding: 12px; - background-color: #1e429f; - color: white; - text-decoration: none; - border-radius: 6px; - font-weight: 600; - transition: background-color 0.3s; -} - -.subscribed__confirmed nav a { - display: block; - padding: 12px; - background-color: #1e429f; - color: white; - text-decoration: none; - border-radius: 6px; - font-weight: 600; - transition: background-color 0.3s; -} - -.notify__btn a:hover, -.notify__btn:hover a { - background-color: #163a7b; -} - -.subscribe__form_container { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - padding: 5px; -} - -.subscribe__form_container p { - font-family: Inter, sans-serif; - font-size: 20px; - font-weight: 400; - line-height: 30px; - color: #6b7280; -} - -.subscribe__form { - background-color: white; - width: 100%; - max-width: 500px; - position: relative; - box-sizing: border-box; - padding: 30px; - box-shadow: rgb(17 12 46 / 15%) 0 48px 100px 0; - border-radius: 8px; - margin-top: 5rem; -} - -.subscribed__confirmed__close__btn { - position: absolute; - top: 12px; - right: 15px; - padding: 5px; - background: none; - border: none; - cursor: pointer; - font-size: 24px; - line-height: 1; - width: 30px; - height: 30px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - transition: background-color 0.3s ease; -} - -.input__group { - margin-bottom: 1.5rem; - display: flex; - flex-direction: column; -} - -.input__group label { - font-family: Inter, sans-serif; - font-size: 16px; - font-weight: 500; - line-height: 24px; - text-align: left; -} - -.input__group__span { - color: #374151; -} - -.input__group input::placeholder { - color: #6b7280; -} - -.input__group input { - padding: 0.75rem; - border: 1px solid #d1d5db; - border-radius: 6px; - font-family: Inter, sans-serif; - font-size: 14px; - font-weight: 400; - line-height: 17.5px; - text-align: left; - color: #000; -} - -.invalid-input { - border-color: #dc2626; - color: red; -} - -.submit__btn { - padding: 1rem; - background-color: #1e429f; - color: white; - border: none; - border-radius: 6px; - cursor: pointer; - transition: background-color 0.3s ease; -} - -.subscribe__button { - width: 100%; -} - -.subscribe__button:disabled { - background-color: #dadada; -} - -.login__message { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 2rem; - text-align: center; -} - -.login__message h1 { - font-size: 32px; - font-weight: 700; - color: #111827; -} - -.login__message p { - font-family: Inter, sans-serif; - font-size: 20px; - font-weight: 400; - line-height: 30px; - color: #6b7280; -} - -.login__message .sub__text { - font-size: 16px; - color: #374151; - margin-top: 1rem; -} - -.already-subscribed { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 1.5rem; - text-align: center; - max-width: 600px; - margin: 0 auto; -} - -.already-subscribed h1 { - font-size: 32px; - font-weight: 700; - color: #1e429f; - text-align: center; -} - -.already-subscribed p { - font-family: Inter, sans-serif; - font-size: 18px; - font-weight: 400; - line-height: 28px; - color: #374151; - text-align: center; -} diff --git a/app/templates/subscribe.hbs b/app/templates/subscribe.hbs deleted file mode 100644 index 1eb4eda5..00000000 --- a/app/templates/subscribe.hbs +++ /dev/null @@ -1,49 +0,0 @@ -{{page-title 'Subscribe'}} - - diff --git a/config/environment.js b/config/environment.js index 18dc1fe2..f0094847 100644 --- a/config/environment.js +++ b/config/environment.js @@ -21,20 +21,14 @@ module.exports = function (environment) { fastboot: { hostWhitelist: [/^localhost:\d+$/, 'dev.realdevsquad.com'], }, - phoneInput: { - lazyLoad: true, - hasPrepend: false, - }, }; if (environment === 'production') { ENV.fastboot.hostWhitelist = ['realdevsquad.com']; - ENV.phoneInput.hasPrepend = true; } if (environment === 'staging') { ENV.fastboot.hostWhitelist = ['beta.realdevsquad.com']; - ENV.phoneInput.hasPrepend = true; } if (environment === 'development') { diff --git a/package.json b/package.json index 87edafbc..88b71842 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ "d3-cloud": "1.2.7", "dotenv": "16.0.2", "ember-d3": "0.5.1", - "ember-phone-input": "^10.0.0", "exists-sync": "0.1.0", "fastboot-app-server": "3.3.2" }, diff --git a/yarn.lock b/yarn.lock index 5ee44be1..a0e258c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3110,15 +3110,6 @@ ember-cli-babel "^7.26.11" ember-modifier-manager-polyfill "^1.2.0" -"@ember/render-modifiers@^2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-2.1.0.tgz#f4fff95a8b5cfbe947ec46644732d511711c5bf9" - integrity sha512-LruhfoDv2itpk0fA0IC76Sxjcnq/7BC6txpQo40hOko8Dn6OxwQfxkPIbZGV0Cz7df+iX+VJrcYzNIvlc3w2EQ== - dependencies: - "@embroider/macros" "^1.0.0" - ember-cli-babel "^7.26.11" - ember-modifier-manager-polyfill "^1.2.0" - "@ember/string@3.1.1": version "3.1.1" resolved "https://registry.yarnpkg.com/@ember/string/-/string-3.1.1.tgz#0a5ac0d1e4925259e41d5c8d55ef616117d47ff0" @@ -9197,16 +9188,6 @@ ember-page-title@8.2.3: "@embroider/addon-shim" "^1.8.7" "@simple-dom/document" "^1.4.0" -ember-phone-input@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/ember-phone-input/-/ember-phone-input-10.0.0.tgz#0aaac5e57e3cbd3f20973138d39c77caf5c6b36b" - integrity sha512-kebV05W7Y2+DN+xSwvPWe0ocVI3gK2UlaOjw8G1g5rw1Aoe0ouFI5ecCs+/5YvHRzPZzpASyrC3w63vpgSo9jA== - dependencies: - "@ember/render-modifiers" "^2.1.0" - "@embroider/addon-shim" "^1.8.7" - intl-tel-input "^18.0.0" - rsvp "^4.8.5" - ember-qunit@8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-8.0.2.tgz#a6346136cba785853f176dfa6ed25e3f0a11b7a0" @@ -11395,11 +11376,6 @@ intersection-observer-admin@~0.3.2: resolved "https://registry.yarnpkg.com/intersection-observer-admin/-/intersection-observer-admin-0.3.3.tgz#176a2a08c1cfa9ec3bc74d81cb9ba6483c30e625" integrity sha512-aKMJPw/8cxybcgYTbnwGn87VgSFbSNNqeChRJahD+ai+jtwlCOdIcEvtuBd2BWO9bPuylVgeQVmGGfX2aS1NIg== -intl-tel-input@^18.0.0: - version "18.5.3" - resolved "https://registry.yarnpkg.com/intl-tel-input/-/intl-tel-input-18.5.3.tgz#20b18431cb802d33c118f52e332e218e641ec09b" - integrity sha512-ncFqSpkdGf2YC/FvAiwBH44KAeRG8L7aqDODEpOvMAT3ZpBtvc/WtwaQ/6X4+HKDTlGkobdBjr6P3nAMwO8jtA== - invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" From ae1a68929fe4c5b8b4c1cffeea6bf9fb69e4be1d Mon Sep 17 00:00:00 2001 From: Lakshay Manchanda <45519620+lakshayman@users.noreply.github.com> Date: Fri, 25 Oct 2024 01:53:10 +0530 Subject: [PATCH 3/3] Dev to Main (Subscription Feature) (#951) * Subscription feature (#936) * feat: add form to collect subscription data * feat: add form to collect subscription data * WIP: add ember-phone-input * feat: add not loggedin and subscribed screen and integreate API * feat: fixing bug * fix: bug to show form even if user is already subscribed * fix: urls * fix: urls * fix: urls * delete: service subscribe test * fix: resolve comments * Update app/components/header.hbs Co-authored-by: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> * fix: comments and remove modal * fix: phone number input * fix: content change * fix: remove card * fix: remove comments * fix:subscribe message --------- Co-authored-by: Vinit khandal <111434418+vinit717@users.noreply.github.com> Co-authored-by: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> * subscription feature fixes (#944) * fix: navbar & css & phone validation * fix: PR comments * feat: add error to in valid input * fix: lint * rename: phoneNumber to phone (#953) --------- Co-authored-by: TEJAS <98630752+tejaskh3@users.noreply.github.com> Co-authored-by: Vinit khandal <111434418+vinit717@users.noreply.github.com> Co-authored-by: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> --- app/components/header.hbs | 2 +- app/components/join-section.hbs | 3 + app/constants/regex.js | 2 + app/constants/urls.js | 1 + app/controllers/subscribe.js | 100 ++++++++++++ app/models/user.js | 3 + app/router.js | 1 + app/routes/subscribe.js | 3 + app/styles/app.css | 2 + app/styles/base-modal.module.css | 6 +- app/styles/join-section.module.css | 27 ++++ app/styles/phone-input.module.css | 23 +++ app/styles/subscribe.module.css | 242 +++++++++++++++++++++++++++++ app/templates/subscribe.hbs | 49 ++++++ config/environment.js | 6 + package.json | 1 + yarn.lock | 24 +++ 17 files changed, 493 insertions(+), 2 deletions(-) create mode 100644 app/constants/regex.js create mode 100644 app/controllers/subscribe.js create mode 100644 app/routes/subscribe.js create mode 100644 app/styles/phone-input.module.css create mode 100644 app/styles/subscribe.module.css create mode 100644 app/templates/subscribe.hbs diff --git a/app/components/header.hbs b/app/components/header.hbs index dfd80d93..54224285 100644 --- a/app/components/header.hbs +++ b/app/components/header.hbs @@ -51,7 +51,7 @@ class="nav__element" href={{this.STATUS_URL}} >Status
  • - {{#if @dev}} + {{#if @dev}}
  • {{! TODO - remove query for dev when it goes to production }} + {{else}}
    diff --git a/app/constants/regex.js b/app/constants/regex.js new file mode 100644 index 00000000..59c5b265 --- /dev/null +++ b/app/constants/regex.js @@ -0,0 +1,2 @@ +export const phoneNumberRegex = + /^[+]{1}(?:[0-9\-\\(\\)\\/.]\s?){6,15}[0-9]{1}$/; diff --git a/app/constants/urls.js b/app/constants/urls.js index b65938f2..e4eaf6e0 100644 --- a/app/constants/urls.js +++ b/app/constants/urls.js @@ -99,3 +99,4 @@ export const SOCIALS = { }; export const ANKUSH_TWITTER = 'https://twitter.com/ankushdharkar'; +export const RDS_TWITTER = 'https://x.com/realdevsquad'; diff --git a/app/controllers/subscribe.js b/app/controllers/subscribe.js new file mode 100644 index 00000000..8fef9c36 --- /dev/null +++ b/app/controllers/subscribe.js @@ -0,0 +1,100 @@ +import Controller from '@ember/controller'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; +import { inject as service } from '@ember/service'; +import { RDS_TWITTER, APPS } from '../constants/urls'; +import { TOAST_OPTIONS } from '../constants/toast-options'; +import { phoneNumberRegex } from '../constants/regex'; + +export default class SubscribeController extends Controller { + @service login; + @tracked isFormOpen = false; + @tracked email = ''; + @tracked phone = ''; + @tracked userData = null; + @tracked isLoading = false; + @tracked showSubscribedMessage = false; + @service toast; + @tracked isPhoneValid = true; + + RDS_TWITTER = RDS_TWITTER; + + constructor() { + super(...arguments); + this.userData = this.login.userData; + } + + get isLoggedIn() { + return this.login.isLoggedIn; + } + + get isSubscribed() { + return this.login.userData.isSubscribed; + } + + get isSubmitDisabled() { + const isPhoneValid = !this.phone || phoneNumberRegex.test(this.phone); + return !this.email || !isPhoneValid; + } + + @action + toggleFormModal() { + this.isFormOpen = !this.isFormOpen; + } + + @action + updateEmail(event) { + this.email = event.target.value; + } + + @action + updatePhone(event) { + this.phone = event.target.value; + this.isPhoneValid = !this.phone || phoneNumberRegex.test(this.phone); + } + + @action + async handleSubmit(event) { + event.preventDefault(); + if (!this.isSubmitDisabled) { + this.isLoading = true; + try { + const url = `${APPS.API_BACKEND}/subscription?dev=true`; + const response = await fetch(url, { + method: 'POST', + body: JSON.stringify({ + email: this.email, + phone: this.phone, + }), + headers: { + 'Content-Type': 'application/json', + }, + credentials: 'include', + }); + if (!response.ok) { + this.toast.error( + 'Something went wrong. Please try again.', + '', + TOAST_OPTIONS, + ); + } else { + this.login.userData.isSubscribed = true; + this.isFormOpen = false; + this.showSubscribedMessage = true; + this.toast.success('🎉 Thankyou for subscribing!', '', TOAST_OPTIONS); + } + } catch (error) { + console.log(error); + this.toast.error( + `Something went wrong. ${error.message}`, + '', + TOAST_OPTIONS, + ); + } finally { + this.isLoading = false; + } + this.email = ''; + this.phone = ''; + } + } +} diff --git a/app/models/user.js b/app/models/user.js index dbd0f80d..1a1caebb 100644 --- a/app/models/user.js +++ b/app/models/user.js @@ -20,4 +20,7 @@ export default class UserModel extends Model { @attr profileURL; @attr profileStatus; @attr website; + @attr isSubscribed; + @attr phoneNumber; + @attr email; } diff --git a/app/router.js b/app/router.js index 111652e7..a78344ed 100644 --- a/app/router.js +++ b/app/router.js @@ -15,4 +15,5 @@ Router.map(function () { this.route('goto'); this.route('events'); this.route('debug'); + this.route('subscribe'); }); diff --git a/app/routes/subscribe.js b/app/routes/subscribe.js new file mode 100644 index 00000000..b2338e80 --- /dev/null +++ b/app/routes/subscribe.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class SubscribeRoute extends Route {} diff --git a/app/styles/app.css b/app/styles/app.css index 9de6edd7..48c90b21 100644 --- a/app/styles/app.css +++ b/app/styles/app.css @@ -41,6 +41,8 @@ @import url("tooltip.module.css"); @import url("debug.module.css"); @import url("unauthenticated.module.css"); +@import url("subscribe.module.css"); +@import url("phone-input.module.css"); * { margin: 0; diff --git a/app/styles/base-modal.module.css b/app/styles/base-modal.module.css index 74c0e666..f44310f4 100644 --- a/app/styles/base-modal.module.css +++ b/app/styles/base-modal.module.css @@ -9,7 +9,11 @@ } .base-modal--show { - display: block; + display: flex; + align-items: center; + justify-content: center; + background-color: #000000b2; + backdrop-filter: blur(5px); } .base-modal--hide { diff --git a/app/styles/join-section.module.css b/app/styles/join-section.module.css index a63cda06..203185e5 100644 --- a/app/styles/join-section.module.css +++ b/app/styles/join-section.module.css @@ -41,6 +41,13 @@ line-height: 175%; } +.links__container { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; +} + .join__link { display: inline-block; margin-top: 2rem; @@ -54,11 +61,23 @@ padding: 1.25rem 3rem; } +.subscribe__link { + display: flex; + justify-content: center; + align-items: center; + gap: 5px; + padding: 1.125rem 3.75rem; +} + .join__link:hover { background-color: var(--color-pink); transition-duration: 250ms; } +.subscribe__link span { + font-size: 1.125rem; +} + .join__link--new { background-color: var(--color-button-disabled); cursor: not-allowed; @@ -126,6 +145,10 @@ font-size: 1.25rem; padding: 1rem 2.5rem; } + + .subscribe__link span { + font-size: 0.75rem; + } } @media (width <=425px) { @@ -147,4 +170,8 @@ font-size: 1rem; padding: 0.75rem 2rem; } + + .subscribe__link span { + font-size: 0.75rem; + } } diff --git a/app/styles/phone-input.module.css b/app/styles/phone-input.module.css new file mode 100644 index 00000000..1ead37c9 --- /dev/null +++ b/app/styles/phone-input.module.css @@ -0,0 +1,23 @@ +.phone-input { + display: flex; + align-items: center; + margin-bottom: 10px; +} + +.country-code-select { + margin-right: 10px; +} + +.phone-number-input { + flex-grow: 1; +} + +.phone-input select, +.phone-input input[type="tel"] { + width: 100%; + padding: 5px; +} + +button { + padding: 5px 10px; +} diff --git a/app/styles/subscribe.module.css b/app/styles/subscribe.module.css new file mode 100644 index 00000000..b610d4d8 --- /dev/null +++ b/app/styles/subscribe.module.css @@ -0,0 +1,242 @@ +@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"); + +.subscribe__container { + background-color: var(--color-white); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2rem; + text-align: center; + min-height: 76vh; +} + +.subscribe__container h1, +.subscribe__form_container h1 { + font-size: 2rem; + font-weight: 700; + color: #111827; + text-align: center; +} + +.subscribe__container p, +.subscribe__form_container p { + font-family: Inter, sans-serif; + font-size: 1.25rem; + font-weight: 400; + line-height: 1.875rem; + text-align: center; +} + +.notification__text { + font-size: 18px; + color: #dc2626; +} + +.sub__text { + font-size: 16px; + color: #374151; +} + +.notify__btn { + font-size: 16px; + background-color: #1e429f; + color: white; + padding: 0.75rem 1.5rem; + border: none; + border-radius: 8px; + cursor: pointer; + transition: background-color 0.3s ease; + text-align: center; +} + +.notify__btn:hover { + background-color: #1558b0; +} + +.notify__btn a { + display: block; + padding: 12px; + background-color: #1e429f; + color: white; + text-decoration: none; + border-radius: 6px; + font-weight: 600; + transition: background-color 0.3s; +} + +.subscribed__confirmed nav a { + display: block; + padding: 12px; + background-color: #1e429f; + color: white; + text-decoration: none; + border-radius: 6px; + font-weight: 600; + transition: background-color 0.3s; +} + +.notify__btn a:hover, +.notify__btn:hover a { + background-color: #163a7b; +} + +.subscribe__form_container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 5px; +} + +.subscribe__form_container p { + font-family: Inter, sans-serif; + font-size: 20px; + font-weight: 400; + line-height: 30px; + color: #6b7280; +} + +.subscribe__form { + background-color: white; + width: 100%; + max-width: 500px; + position: relative; + box-sizing: border-box; + padding: 30px; + box-shadow: rgb(17 12 46 / 15%) 0 48px 100px 0; + border-radius: 8px; + margin-top: 5rem; +} + +.subscribed__confirmed__close__btn { + position: absolute; + top: 12px; + right: 15px; + padding: 5px; + background: none; + border: none; + cursor: pointer; + font-size: 24px; + line-height: 1; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + transition: background-color 0.3s ease; +} + +.input__group { + margin-bottom: 1.5rem; + display: flex; + flex-direction: column; +} + +.input__group label { + font-family: Inter, sans-serif; + font-size: 16px; + font-weight: 500; + line-height: 24px; + text-align: left; +} + +.input__group__span { + color: #374151; +} + +.input__group input::placeholder { + color: #6b7280; +} + +.input__group input { + padding: 0.75rem; + border: 1px solid #d1d5db; + border-radius: 6px; + font-family: Inter, sans-serif; + font-size: 14px; + font-weight: 400; + line-height: 17.5px; + text-align: left; + color: #000; +} + +.invalid-input { + border-color: #dc2626; + color: red; +} + +.submit__btn { + padding: 1rem; + background-color: #1e429f; + color: white; + border: none; + border-radius: 6px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.subscribe__button { + width: 100%; +} + +.subscribe__button:disabled { + background-color: #dadada; +} + +.login__message { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2rem; + text-align: center; +} + +.login__message h1 { + font-size: 32px; + font-weight: 700; + color: #111827; +} + +.login__message p { + font-family: Inter, sans-serif; + font-size: 20px; + font-weight: 400; + line-height: 30px; + color: #6b7280; +} + +.login__message .sub__text { + font-size: 16px; + color: #374151; + margin-top: 1rem; +} + +.already-subscribed { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1.5rem; + text-align: center; + max-width: 600px; + margin: 0 auto; +} + +.already-subscribed h1 { + font-size: 32px; + font-weight: 700; + color: #1e429f; + text-align: center; +} + +.already-subscribed p { + font-family: Inter, sans-serif; + font-size: 18px; + font-weight: 400; + line-height: 28px; + color: #374151; + text-align: center; +} diff --git a/app/templates/subscribe.hbs b/app/templates/subscribe.hbs new file mode 100644 index 00000000..1eb4eda5 --- /dev/null +++ b/app/templates/subscribe.hbs @@ -0,0 +1,49 @@ +{{page-title 'Subscribe'}} + + diff --git a/config/environment.js b/config/environment.js index f0094847..18dc1fe2 100644 --- a/config/environment.js +++ b/config/environment.js @@ -21,14 +21,20 @@ module.exports = function (environment) { fastboot: { hostWhitelist: [/^localhost:\d+$/, 'dev.realdevsquad.com'], }, + phoneInput: { + lazyLoad: true, + hasPrepend: false, + }, }; if (environment === 'production') { ENV.fastboot.hostWhitelist = ['realdevsquad.com']; + ENV.phoneInput.hasPrepend = true; } if (environment === 'staging') { ENV.fastboot.hostWhitelist = ['beta.realdevsquad.com']; + ENV.phoneInput.hasPrepend = true; } if (environment === 'development') { diff --git a/package.json b/package.json index 88b71842..87edafbc 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "d3-cloud": "1.2.7", "dotenv": "16.0.2", "ember-d3": "0.5.1", + "ember-phone-input": "^10.0.0", "exists-sync": "0.1.0", "fastboot-app-server": "3.3.2" }, diff --git a/yarn.lock b/yarn.lock index a0e258c2..5ee44be1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3110,6 +3110,15 @@ ember-cli-babel "^7.26.11" ember-modifier-manager-polyfill "^1.2.0" +"@ember/render-modifiers@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-2.1.0.tgz#f4fff95a8b5cfbe947ec46644732d511711c5bf9" + integrity sha512-LruhfoDv2itpk0fA0IC76Sxjcnq/7BC6txpQo40hOko8Dn6OxwQfxkPIbZGV0Cz7df+iX+VJrcYzNIvlc3w2EQ== + dependencies: + "@embroider/macros" "^1.0.0" + ember-cli-babel "^7.26.11" + ember-modifier-manager-polyfill "^1.2.0" + "@ember/string@3.1.1": version "3.1.1" resolved "https://registry.yarnpkg.com/@ember/string/-/string-3.1.1.tgz#0a5ac0d1e4925259e41d5c8d55ef616117d47ff0" @@ -9188,6 +9197,16 @@ ember-page-title@8.2.3: "@embroider/addon-shim" "^1.8.7" "@simple-dom/document" "^1.4.0" +ember-phone-input@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ember-phone-input/-/ember-phone-input-10.0.0.tgz#0aaac5e57e3cbd3f20973138d39c77caf5c6b36b" + integrity sha512-kebV05W7Y2+DN+xSwvPWe0ocVI3gK2UlaOjw8G1g5rw1Aoe0ouFI5ecCs+/5YvHRzPZzpASyrC3w63vpgSo9jA== + dependencies: + "@ember/render-modifiers" "^2.1.0" + "@embroider/addon-shim" "^1.8.7" + intl-tel-input "^18.0.0" + rsvp "^4.8.5" + ember-qunit@8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-8.0.2.tgz#a6346136cba785853f176dfa6ed25e3f0a11b7a0" @@ -11376,6 +11395,11 @@ intersection-observer-admin@~0.3.2: resolved "https://registry.yarnpkg.com/intersection-observer-admin/-/intersection-observer-admin-0.3.3.tgz#176a2a08c1cfa9ec3bc74d81cb9ba6483c30e625" integrity sha512-aKMJPw/8cxybcgYTbnwGn87VgSFbSNNqeChRJahD+ai+jtwlCOdIcEvtuBd2BWO9bPuylVgeQVmGGfX2aS1NIg== +intl-tel-input@^18.0.0: + version "18.5.3" + resolved "https://registry.yarnpkg.com/intl-tel-input/-/intl-tel-input-18.5.3.tgz#20b18431cb802d33c118f52e332e218e641ec09b" + integrity sha512-ncFqSpkdGf2YC/FvAiwBH44KAeRG8L7aqDODEpOvMAT3ZpBtvc/WtwaQ/6X4+HKDTlGkobdBjr6P3nAMwO8jtA== + invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"