0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-28 15:41:25 -05:00

🎉 Add newsletter subscription modal

This commit is contained in:
Eva 2022-03-22 18:27:06 +01:00 committed by Andrey Antukh
parent b7e0619e9a
commit 5e7e055539
14 changed files with 270 additions and 19 deletions

View file

@ -8,6 +8,7 @@
### :arrow_up: Deps updates
### :heart: Community contributions by (Thank you!)
## 1.13.0-beta
### :boom: Breaking changes

View file

@ -342,13 +342,26 @@
;; --- MUTATION: Update Profile (own)
(defn- update-profile-newsletter-subscribed
[conn profile-id newsletter-subscribed]
(let [profile (profile/retrieve-profile-data conn profile-id)
props (:props profile)
props (assoc props :newsletter-subscribed newsletter-subscribed)
]
(db/update! conn :profile
{:props (db/tjson props)}
{:id profile-id})))
(defn- update-profile
[conn {:keys [id fullname lang theme] :as params}]
[conn {:keys [id fullname lang theme newsletter-subscribed] :as params}]
(let [profile (db/update! conn :profile
{:fullname fullname
:lang lang
:theme theme}
{:id id})]
{:id id})
profile (if (some? newsletter-subscribed)
(update-profile-newsletter-subscribed conn id newsletter-subscribed)
profile)]
(-> profile
(profile/decode-profile-row)
(profile/strip-private-attrs))))

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -109,6 +109,38 @@
flex-direction: column;
max-width: 368px;
width: 100%;
.newsletter-subs {
border-bottom: 1px solid $color-gray-20;
border-top: 1px solid $color-gray-20;
padding: 30px 0;
margin-bottom: 31px;
.newsletter-title {
font-family: "worksans", sans-serif;
color: $color-gray-30;
font-size: $fs14;
}
label {
font-family: "worksans", sans-serif;
color: $color-gray-60;
font-size: $fs12;
margin-right: -17px;
margin-bottom: 13px;
}
.info {
font-family: "worksans", sans-serif;
color: $color-gray-30;
font-size: $fs12;
margin-bottom: 8px;
}
.input-checkbox label {
align-items: flex-start;
}
}
}
.options-form,

View file

@ -996,6 +996,57 @@
}
}
}
&.newsletter {
padding: $size-5 0 0 0;
flex-direction: column;
min-width: 555px;
.modal-top {
padding: 87px 40px 0 40px;
color: $color-gray-60;
display: flex;
flex-direction: column;
h1 {
font-family: sourcesanspro;
font-weight: bold;
font-size: $fs36;
margin-bottom: 0.75rem;
}
p {
font-family: sourcesanspro;
font-weight: 500;
font-size: $fs16;
margin-bottom: 1.5rem;
}
}
.modal-bottom {
margin: 0 32px;
padding: 32px 0;
color: $color-gray-60;
display: flex;
flex-direction: column;
border-top: 1px solid $color-gray-10;
p {
font-family: "worksans", sans-serif;
text-align: left;
color: $color-gray-30;
}
}
.modal-footer {
padding: 17px;
display: flex;
justify-content: flex-end;
.btn-secondary {
margin-right: 16px;
}
}
}
}
.deco {
@ -1004,6 +1055,23 @@
top: -18px;
width: 60px;
&.top {
width: 183px;
top: -106px;
left: 161px;
}
&.newsletter-right {
left: 515px;
top: 50px;
}
&.newsletter-left {
width: 26px;
left: -15px;
top: -15px;
}
&.right {
left: 590px;
top: 0;

View file

@ -304,7 +304,7 @@
(let [mdata (meta data)
on-success (:on-success mdata identity)
on-error (:on-error mdata #(rx/throw %))]
(->> (rp/mutation :update-profile data)
(->> (rp/mutation :update-profile (dissoc data :props))
(rx/catch on-error)
(rx/mapcat
(fn [_]
@ -392,7 +392,6 @@
(->> (rp/mutation :update-profile-props {:props props})
(rx/map (constantly (fetch-profile)))))))))
(defn mark-questions-as-answered
[]
(ptk/reify ::mark-questions-as-answered

View file

@ -59,15 +59,15 @@
klass (str more-classes " "
(dom/classnames
:focus @focus?
:valid (and touched? (not error))
:invalid (and touched? error)
:disabled disabled
:empty (and is-text? (str/empty? value))
:with-icon (not (nil? help-icon'))
:custom-input is-text?
:input-radio is-radio?
:input-checkbox is-checkbox?))
:focus @focus?
:valid (and touched? (not error))
:invalid (and touched? error)
:disabled disabled
:empty (and is-text? (str/empty? value))
:with-icon (not (nil? help-icon'))
:custom-input is-text?
:input-radio is-radio?
:input-checkbox is-checkbox?))
swap-text-password
(fn []
@ -97,6 +97,7 @@
:placeholder label
:on-change on-change
:type @type')
(cond-> (and value is-checkbox?) (assoc :default-checked value))
(obj/clj->props))]
[:div
@ -210,7 +211,7 @@
(let [form (or form (mf/use-ctx form-ctx))]
[:input.btn-primary.btn-large
{:name "submit"
:class (when-not (:valid @form) "btn-disabled")
:class (when (or (not (:valid @form)) (true? disabled)) "btn-disabled")
:disabled (or (not (:valid @form)) (true? disabled))
:on-click on-click
:value label

View file

@ -10,6 +10,7 @@
[app.main.data.modal :as modal]
[app.main.data.users :as du]
[app.main.store :as st]
[app.main.ui.onboarding.newsletter]
[app.main.ui.onboarding.questions]
[app.main.ui.onboarding.team-choice]
[app.main.ui.onboarding.templates]
@ -154,7 +155,7 @@
skip
(mf/use-callback
(st/emitf (modal/hide)
(modal/show {:type :onboarding-choice})
(modal/show {:type :onboarding-newsletter-modal})
(du/mark-onboarding-as-viewed)))]
(mf/use-layout-effect

View file

@ -0,0 +1,47 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) UXBOX Labs SL
(ns app.main.ui.onboarding.newsletter
(:require
[app.main.data.messages :as dm]
[app.main.data.modal :as modal]
[app.main.data.users :as du]
[app.main.store :as st]
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]))
(mf/defc onboarding-newsletter-modal
{::mf/register modal/components
::mf/register-as :onboarding-newsletter-modal}
[]
(let [message (tr "onboarding.newsletter.acceptance-message")
accept
(mf/use-callback
(fn []
(st/emit! (dm/success message)
(modal/show {:type :onboarding-choice})
(du/update-profile-props {:newsletter-subscribed true}))))
decline
(mf/use-callback
(fn []
(st/emit! (modal/show {:type :onboarding-choice})
(du/update-profile-props {:newsletter-subscribed false}))))]
[:div.modal-overlay
[:div.modal-container.onboarding.newsletter.animated.fadeInUp
[:div.modal-top
[:h1.newsletter-title {:data-test "onboarding-newsletter-title"} (tr "onboarding.newsletter.title")]
[:p (tr "onboarding.newsletter.desc")]]
[:div.modal-bottom
[:p (tr "onboarding.newsletter.privacy1") [:a {:target "_blank" :href "https://penpot.app/privacy.html"} (tr "onboarding.newsletter.policy")]]
[:p (tr "onboarding.newsletter.privacy2")]]
[:div.modal-footer
[:button.btn-secondary {:on-click decline} (tr "onboarding.newsletter.decline")]
[:button.btn-primary {:on-click accept} (tr "onboarding.newsletter.accept")]]
[:img.deco.top {:src "images/deco-newsletter.png" :border "0"}]
[:img.deco.newsletter-left {:src "images/deco-news-left.png" :border "0"}]
[:img.deco.newsletter-right {:src "images/deco-news-right.png" :border "0"}]]]))

View file

@ -43,13 +43,17 @@
[{:keys [locale] :as props}]
(let [profile (mf/deref refs/profile)
form (fm/use-form :spec ::profile-form
:initial profile)]
:initial profile)
disabled-button (mf/use-state true)
activate-btn #(reset! disabled-button false)]
[:& fm/form {:on-submit on-submit
:form form
:class "profile-form"}
[:div.fields-row
[:& fm/input
{:type "text"
:on-key-down activate-btn
:name :fullname
:label (t locale "dashboard.your-name")}]]
@ -66,8 +70,19 @@
[:a {:on-click #(modal/show! :change-email {})}
(t locale "dashboard.change-email")]]]]
[:div.newsletter-subs
[:p.newsletter-title (tr "dashboard.newsletter-title")]
[:& fm/input {:name :newsletter-subscribed
:class "check-primary"
:type "checkbox"
:label (tr "dashboard.newsletter-msg")
:on-click activate-btn}]
[:p.info (tr "onboarding.newsletter.privacy1") [:a {:target "_blank" :href "https://penpot.app/privacy.html"} (tr "onboarding.newsletter.policy")]]
[:p.info (tr "onboarding.newsletter.privacy2")]]
[:& fm/submit-button
{:label (t locale "dashboard.update-settings")}]
{:label (t locale "dashboard.save-settings")
:disabled @disabled-button}]
[:div.links
[:div.link-item

View file

@ -581,7 +581,19 @@ msgstr "Search results"
msgid "dashboard.type-something"
msgstr "Type to search results"
#: src/app/main/ui/settings/profile.cljs, src/app/main/ui/settings/password.cljs, src/app/main/ui/settings/options.cljs
#: src/app/main/ui/settings/profile.cljs
msgid "dashboard.save-settings"
msgstr "Save settings"
#: src/app/main/ui/settings/profile.cljs
msgid "dashboard.newsletter-title"
msgstr "Newsletter subscription"
#: src/app/main/ui/settings/profile.cljs
msgid "dashboard.newsletter-msg"
msgstr "Send me news, product updates and recommendations about Penpot."
#: src/app/main/ui/settings/password.cljs, src/app/main/ui/settings/options.cljs
msgid "dashboard.update-settings"
msgstr "Update settings"
@ -1855,6 +1867,30 @@ msgstr ""
msgid "onboarding.welcome.title"
msgstr "Welcome to Penpot"
msgid "onboarding.newsletter.title"
msgstr "Want to receive Penpot news?"
msgid "onboarding.newsletter.desc"
msgstr "Subscribe to our newsletter to stay up to date with product development progress and news."
msgid "onboarding.newsletter.privacy1"
msgstr "Because we care about privacy, here's our "
msgid "onboarding.newsletter.policy"
msgstr "Privacy Policy."
msgid "onboarding.newsletter.privacy2"
msgstr "We will only send relevant emails to you. You can unsubscribe at any time in your user profile or via the unsubscribe link in any of our newsletters."
msgid "onboarding.newsletter.accept"
msgstr "Yes, subscribe"
msgid "onboarding.newsletter.decline"
msgstr "No, thanks"
msgid "onboarding.newsletter.acceptance-message"
msgstr "Your subscription request has been sent, we will send you an email to confirm it."
#: src/app/main/ui/auth/recovery.cljs
msgid "profile.recovery.go-to-login"
msgstr "Go to login"

View file

@ -587,7 +587,20 @@ msgstr "Resultados de búsqueda"
msgid "dashboard.type-something"
msgstr "Escribe algo para buscar"
#: src/app/main/ui/settings/profile.cljs, src/app/main/ui/settings/password.cljs, src/app/main/ui/settings/options.cljs
#: src/app/main/ui/settings/profile.cljs
msgid "dashboard.save-settings"
msgstr "Guardar opciones"
#: src/app/main/ui/settings/profile.cljs
msgid "dashboard.newsletter-title"
msgstr "Suscripción a newsletter"
#: src/app/main/ui/settings/profile.cljs
msgid "dashboard.newsletter-msg"
msgstr "Envíame noticias, actualizaciones de producto y recomendaciones sobre Penpot."
#: src/app/main/ui/settings/password.cljs, src/app/main/ui/settings/options.cljs
msgid "dashboard.update-settings"
msgstr "Actualizar opciones"
@ -1876,6 +1889,31 @@ msgstr ""
msgid "onboarding.welcome.title"
msgstr "Te damos la bienvenida a Penpot"
msgid "onboarding.newsletter.title"
msgstr "¿Quieres recibir noticias sobre Penpot?"
msgid "onboarding.newsletter.desc"
msgstr "Suscríbete a nuestra newsletter para estar al día de los progresos del producto y noticias."
msgid "onboarding.newsletter.privacy1"
msgstr "Porque nos importa la privacidad, aquí puedes ver nuestra "
msgid "onboarding.newsletter.policy"
msgstr "Política de Privacidad."
msgid "onboarding.newsletter.privacy2"
msgstr "Sólo te enviaremos emails relevantes para ti. Puedes desuscribirte en cualquier momento desde tu perfil o usando el vínculo de desuscripción en cualquiera de nuestras newsletters."
msgid "onboarding.newsletter.accept"
msgstr "Si, suscribirme"
msgid "onboarding.newsletter.decline"
msgstr "No, gracias"
msgid "onboarding.newsletter.acceptance-message"
msgstr "Tu solicitud de suscripción ha sido enviada, te haremos una confirmación a tu email"
#: src/app/main/ui/auth/recovery.cljs
msgid "profile.recovery.go-to-login"
msgstr "Ir al login"