From 9385adafacc1f472a23ad59adf1895e2aed9fc36 Mon Sep 17 00:00:00 2001 From: Alexander Frolov Date: Fri, 14 Jul 2023 15:18:27 +0400 Subject: [PATCH] Minor refactoring for welcome view (#2333) * Minor refactoring for welcome view ### What's done: * Moved gradients to const strings * Moved useful welcome menu functions to external `WelcomeUtils.kt` file --- .../mobile/SaveWelcomeMobileView.kt | 12 +- .../frontend/components/views/AbstractView.kt | 3 +- .../views/welcome/MarketingTitles.kt | 2 +- .../views/welcome/SaveWelcomeView.kt | 160 +++--------------- .../components/views/welcome/WelcomeUtils.kt | 153 +++++++++++++++++ .../views/welcome/pagers/WelcomePager.kt | 2 +- .../save/frontend/utils/JsUtils.kt | 6 +- 7 files changed, 190 insertions(+), 148 deletions(-) create mode 100644 save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/WelcomeUtils.kt diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/mobile/SaveWelcomeMobileView.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/mobile/SaveWelcomeMobileView.kt index 617b3828f7..29f56f37a6 100644 --- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/mobile/SaveWelcomeMobileView.kt +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/mobile/SaveWelcomeMobileView.kt @@ -3,12 +3,13 @@ package com.saveourtool.save.frontend.components.mobile import com.saveourtool.save.frontend.components.views.welcome.chevron -import com.saveourtool.save.frontend.components.views.welcome.pagers.allWelcomePagers +import com.saveourtool.save.frontend.components.views.welcome.pagers.allSaveWelcomePagers import com.saveourtool.save.frontend.components.views.welcome.pagers.renderReadMorePage -import com.saveourtool.save.frontend.components.views.welcome.welcomeMarketingTitle +import com.saveourtool.save.frontend.components.views.welcome.saveWelcomeMarketingTitle import com.saveourtool.save.frontend.externals.animations.animator import com.saveourtool.save.frontend.externals.animations.scrollContainer import com.saveourtool.save.frontend.externals.animations.scrollPage +import com.saveourtool.save.frontend.utils.SAVE_LIGHT_GRADIENT import com.saveourtool.save.frontend.utils.particles import js.core.jso @@ -26,8 +27,7 @@ import web.cssom.* val saveWelcomeMobileView: VFC = VFC { div { style = jso { - background = - "-webkit-linear-gradient(270deg, rgb(209, 229, 235), rgb(217, 215, 235))".unsafeCast() + background = SAVE_LIGHT_GRADIENT.unsafeCast() } particles() sorryYourScreenIsTooSmall() @@ -42,7 +42,7 @@ private fun ChildrenBuilder.sorryYourScreenIsTooSmall() { @Suppress("EMPTY_BLOCK_STRUCTURE_ERROR") scrollContainer { scrollPage {} - allWelcomePagers.forEach { pager -> + allSaveWelcomePagers.forEach { pager -> scrollPage { } pager.forEach { scrollPage { @@ -88,6 +88,6 @@ private fun ChildrenBuilder.title() { div { className = ClassName("row justify-content-center mx-auto") // Marketing information - welcomeMarketingTitle("text-primary", true) + saveWelcomeMarketingTitle("text-primary", true) } } diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/AbstractView.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/AbstractView.kt index c903b7ae91..be6d07b8f1 100644 --- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/AbstractView.kt +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/AbstractView.kt @@ -1,6 +1,7 @@ package com.saveourtool.save.frontend.components.views import com.saveourtool.save.frontend.utils.ComponentWithScope +import com.saveourtool.save.frontend.utils.SAVE_BLUE_GRADIENT import react.* @@ -15,7 +16,7 @@ abstract class AbstractView

(private val hasBg: Boolean = t override fun componentDidMount() { val style = if (hasBg) { Style( - "-webkit-linear-gradient(270deg, rgb(0,20,73), rgb(13,71,161))", + SAVE_BLUE_GRADIENT, "", "transparent", "px-0", diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/MarketingTitles.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/MarketingTitles.kt index 5ffc13b38e..bc02d086df 100644 --- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/MarketingTitles.kt +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/MarketingTitles.kt @@ -18,7 +18,7 @@ import web.cssom.* * @param textColor * @param isDark */ -fun ChildrenBuilder.welcomeMarketingTitle(textColor: String, isDark: Boolean = false) { +fun ChildrenBuilder.saveWelcomeMarketingTitle(textColor: String, isDark: Boolean = false) { div { className = ClassName("col-4 text-left mt-5 $textColor") marketingTitle("Software", isDark) diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/SaveWelcomeView.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/SaveWelcomeView.kt index 14396cdece..3e740824ad 100644 --- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/SaveWelcomeView.kt +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/SaveWelcomeView.kt @@ -22,13 +22,8 @@ import com.saveourtool.save.validation.FrontendRoutes import js.core.jso import org.w3c.fetch.Headers import react.* -import react.dom.html.ReactHTML.a import react.dom.html.ReactHTML.div -import react.dom.html.ReactHTML.form -import react.dom.html.ReactHTML.h4 -import react.dom.html.ReactHTML.hr import react.dom.html.ReactHTML.main -import react.dom.html.ReactHTML.p import react.dom.html.ReactHTML.span import web.cssom.* @@ -54,8 +49,7 @@ val saveWelcomeView: FC = FC { props -> className = ClassName("page-header align-items-start") style = jso { height = "100vh".unsafeCast() - background = - "-webkit-linear-gradient(270deg, rgb(0,20,73), rgb(13,71,161))".unsafeCast() + background = SAVE_BLUE_GRADIENT.unsafeCast() position = Position.relative } span { @@ -67,7 +61,7 @@ val saveWelcomeView: FC = FC { props -> className = ClassName("row justify-content-center") // Marketing information - welcomeMarketingTitle("text-white") + saveWelcomeMarketingTitle("text-white") // Sign-in header div { @@ -76,7 +70,24 @@ val saveWelcomeView: FC = FC { props -> className = ClassName("card z-index-0 fadeIn3 fadeInBottom") // if user is not logged in - he needs to input credentials props.userInfo?.let { - welcomeUserView(props.userInfo) + welcomeUserMenu(props.userInfo) { + div { + className = ClassName("text-sm") + menuTextAndLink("Contests", "/#/${FrontendRoutes.CONTESTS.path}", faCode) + hrNoMargin() + menuTextAndLink("List of Projects", "#/${FrontendRoutes.PROJECTS.path}", faExternalLinkAlt) + hrNoMargin() + menuTextAndLink("Benchmarks Archive", "/#/${FrontendRoutes.AWESOME_BENCHMARKS.path}", faFolderOpen) + hrNoMargin() + menuTextAndLink("Create new organization", "/#/${FrontendRoutes.CREATE_ORGANIZATION.path}", faUser) + if (props.userInfo.isSuperAdmin()) { + hrNoMargin() + menuTextAndLink("Manage organizations", "/#/${FrontendRoutes.MANAGE_ORGANIZATIONS.path}", faUser) + } + hrNoMargin() + menuTextAndLink("New project in organization", "/#/${FrontendRoutes.CREATE_PROJECT.path}", faPlus) + } + } } ?: run { inputCredentialsView(oauthProviders) @@ -91,8 +102,7 @@ val saveWelcomeView: FC = FC { props -> div { className = ClassName("min-vh-100") style = jso { - background = - "-webkit-linear-gradient(270deg, rgb(209, 229, 235), rgb(217, 215, 235))".unsafeCast() + background = SAVE_LIGHT_GRADIENT.unsafeCast() } renderGeneralInfoPage() @@ -100,7 +110,7 @@ val saveWelcomeView: FC = FC { props -> @Suppress("EMPTY_BLOCK_STRUCTURE_ERROR") scrollContainer { scrollPage { } - allWelcomePagers.forEach { pager -> + allSaveWelcomePagers.forEach { pager -> scrollPage { } scrollPage { pager.forEach { @@ -127,129 +137,3 @@ external interface WelcomeProps : PropsWithChildren { */ var userInfo: UserInfo? } - -@Suppress("TOO_LONG_FUNCTION") -private fun ChildrenBuilder.welcomeUserView(userInfo: UserInfo?) { - div { - className = ClassName("card-header p-0 position-relative mt-n4 mx-3 z-index-2 rounded") - div { - className = ClassName("shadow-primary border-radius-lg py-3 pe-1 rounded") - style = jso { - backgroundColor = "#3075c0".unsafeCast() - } - h4 { - className = ClassName("text-white font-weight-bolder text-center mt-2 mb-0") - div { - className = ClassName("row") - div { - className = ClassName("col text-center px-1 mb-3") - fontAwesomeIcon(icon = faHome) - } - } - +"Welcome, ${userInfo?.name}!" - } - } - } - - div { - className = ClassName("card-body") - div { - className = ClassName("text-sm") - menuTextAndLink("Contests", "/#/${FrontendRoutes.CONTESTS.path}", faCode) - hrNoMargin() - menuTextAndLink("List of Projects", "#/${FrontendRoutes.PROJECTS.path}", faExternalLinkAlt) - hrNoMargin() - menuTextAndLink("Benchmarks Archive", "/#/${FrontendRoutes.AWESOME_BENCHMARKS.path}", faFolderOpen) - hrNoMargin() - menuTextAndLink("Create new organization", "/#/${FrontendRoutes.CREATE_ORGANIZATION.path}", faUser) - if (userInfo.isSuperAdmin()) { - hrNoMargin() - menuTextAndLink("Manage organizations", "/#/${FrontendRoutes.MANAGE_ORGANIZATIONS.path}", faUser) - } - hrNoMargin() - menuTextAndLink("New project in organization", "/#/${FrontendRoutes.CREATE_PROJECT.path}", faPlus) - } - } -} - -@Suppress("TOO_LONG_FUNCTION") -private fun ChildrenBuilder.inputCredentialsView(oauthProviders: List) { - div { - className = ClassName("card-header p-0 position-relative mt-n4 mx-3 z-index-2 rounded") - div { - className = ClassName("shadow-primary border-radius-lg py-3 pe-1 rounded") - style = jso { - backgroundColor = "#3075c0".unsafeCast() - } - h4 { - className = ClassName("text-white font-weight-bolder text-center mt-2 mb-3") - +"Sign in" - } - div { - className = ClassName("row") - oauthProviders.map { - processRegistrationId( - OauthProvidersFeConfig( - size = 3.rem, - it, - ) - ) - } - } - } - } - - div { - className = ClassName("card-body") - form { - className = ClassName("needs-validation") - div { - className = ClassName("mt-4 text-sm text-center") - p { - className = ClassName("mb-0") - +"Don't have an account?" - } - - div { - className = ClassName("text-sm text-center") - h4 { - style = jso { - color = "#3075c0".unsafeCast() - } - a { - href = "#/${FrontendRoutes.PROJECTS.path}" - className = ClassName("text-gradient font-weight-bold ml-2 mr-2") - +"Continue " - fontAwesomeIcon(icon = faSignInAlt) - } - } - +"with limited functionality" - } - } - } - } -} - -private fun ChildrenBuilder.menuTextAndLink(text: String, link: String, icon: FontAwesomeIconModule) { - a { - className = ClassName("text-gradient font-weight-bold ml-2 mr-2") - href = link - h4 { - style = jso { - color = "#3075c0".unsafeCast() - marginBottom = "0.0em".unsafeCast() - } - fontAwesomeIcon(icon = icon, "ml-2 mr-2") - +text - } - } -} - -private fun ChildrenBuilder.hrNoMargin() { - hr { - style = jso { - marginTop = "0.0em".unsafeCast() - marginBottom = "0.0em".unsafeCast() - } - } -} diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/WelcomeUtils.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/WelcomeUtils.kt new file mode 100644 index 0000000000..158ed60372 --- /dev/null +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/WelcomeUtils.kt @@ -0,0 +1,153 @@ +/** + * File containing utils for welcome views rendering + */ + +package com.saveourtool.save.frontend.components.views.welcome + +import com.saveourtool.save.frontend.externals.fontawesome.* +import com.saveourtool.save.frontend.utils.OauthProvidersFeConfig +import com.saveourtool.save.frontend.utils.processRegistrationId +import com.saveourtool.save.info.OauthProviderInfo +import com.saveourtool.save.info.UserInfo +import com.saveourtool.save.validation.FrontendRoutes +import js.core.jso +import react.ChildrenBuilder +import react.dom.html.ReactHTML.div +import react.dom.html.ReactHTML.form +import react.dom.html.ReactHTML.h4 +import react.dom.html.ReactHTML.hr +import react.dom.html.ReactHTML.p +import react.router.dom.Link +import web.cssom.* + +/** + * @param oauthProviders + */ +@Suppress("TOO_LONG_FUNCTION") +internal fun ChildrenBuilder.inputCredentialsView(oauthProviders: List) { + div { + className = ClassName("card-header p-0 position-relative mt-n4 mx-3 z-index-2 rounded") + div { + className = ClassName("shadow-primary border-radius-lg py-3 pe-1 rounded") + style = jso { + backgroundColor = "#3075c0".unsafeCast() + } + h4 { + className = ClassName("text-white font-weight-bolder text-center mt-2 mb-3") + +"Sign in" + } + div { + className = ClassName("row") + oauthProviders.map { + processRegistrationId( + OauthProvidersFeConfig( + size = @Suppress("MAGIC_NUMBER") 3.rem, + it, + ) + ) + } + } + } + } + + div { + className = ClassName("card-body") + form { + className = ClassName("needs-validation") + div { + className = ClassName("mt-4 text-sm text-center") + p { + className = ClassName("mb-0") + +"Don't have an account?" + } + + div { + className = ClassName("text-sm text-center") + h4 { + style = jso { + color = "#3075c0".unsafeCast() + } + Link { + to = "#/${FrontendRoutes.PROJECTS.path}" + className = ClassName("text-gradient font-weight-bold ml-2 mr-2") + +"Continue " + fontAwesomeIcon(icon = faSignInAlt) + } + } + +"with limited functionality" + } + } + } + } +} + +/** + * Render nice menu with options built from [renderMenu] + * + * @param userInfo current [UserInfo] + * @param renderMenu callback to render menu options + */ +internal fun ChildrenBuilder.welcomeUserMenu( + userInfo: UserInfo?, + renderMenu: ChildrenBuilder.() -> Unit +) { + div { + className = ClassName("card-header p-0 position-relative mt-n4 mx-3 z-index-2 rounded") + div { + className = ClassName("shadow-primary border-radius-lg py-3 pe-1 rounded") + style = jso { + backgroundColor = "#3075c0".unsafeCast() + } + h4 { + className = ClassName("text-white font-weight-bolder text-center mt-2 mb-0") + div { + className = ClassName("row") + div { + className = ClassName("col text-center px-1 mb-3") + fontAwesomeIcon(icon = faHome) + } + } + +"Welcome, ${userInfo?.name}!" + } + } + } + + div { + className = ClassName("card-body") + renderMenu() + } +} + +/** + * Render styled [text] with [link] and leading [icon] + * + * @param text [String] to display + * @param link that menu options points to + * @param icon [FontAwesomeIcon] to display + */ +internal fun ChildrenBuilder.menuTextAndLink(text: String, link: String, icon: FontAwesomeIconModule) { + Link { + className = ClassName("text-gradient font-weight-bold ml-2 mr-2") + to = link + h4 { + style = jso { + color = "#3075c0".unsafeCast() + marginBottom = "0.0em".unsafeCast() + } + fontAwesomeIcon(icon = icon, "ml-2 mr-2") + +text + } + } +} + +/** + * Render horizontal line with [Margin] equals to `0.0em` + */ +internal fun ChildrenBuilder.hrNoMargin() { + hr { + style = jso { + marginTop = "0.0em".unsafeCast() + marginBottom = "0.0em".unsafeCast() + } + } +} diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/pagers/WelcomePager.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/pagers/WelcomePager.kt index d79826b218..4a3e053af6 100644 --- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/pagers/WelcomePager.kt +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/views/welcome/pagers/WelcomePager.kt @@ -3,7 +3,7 @@ package com.saveourtool.save.frontend.components.views.welcome.pagers import com.saveourtool.save.frontend.externals.animations.Animation import react.ChildrenBuilder -val allWelcomePagers = listOf( +val allSaveWelcomePagers = listOf( // listOf(HighLevelSave), listOf(SloganAboutCi), listOf(GeneralInfoFirstPicture, GeneralInfoSecondPicture, GeneralInfoThirdPicture, GeneralInfoFourthPicture), diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/utils/JsUtils.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/utils/JsUtils.kt index e9d8bd87e1..ca19371a42 100644 --- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/utils/JsUtils.kt +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/utils/JsUtils.kt @@ -14,6 +14,10 @@ import kotlinx.browser.window private const val SUPER_ADMIN_MESSAGE = "Keep in mind that you are super admin, so you are able to manage organization regardless of your organization permissions." +const val SAVE_BLUE_GRADIENT = "-webkit-linear-gradient(270deg, rgb(0,20,73), rgb(13,71,161))" + +const val SAVE_LIGHT_GRADIENT = "-webkit-linear-gradient(270deg, rgb(209, 229, 235), rgb(217, 215, 235))" + /** * @property globalBackground * @property topBarBgColor @@ -29,7 +33,7 @@ enum class Style( val marginBottomForTopBar: String, ) { BLUE( - "-webkit-linear-gradient(270deg, rgb(0,20,73), rgb(13,71,161))", + SAVE_BLUE_GRADIENT, "", "transparent", "px-0",