]> source.dussan.org Git - sonarqube.git/commitdiff
SONARCLOUD-62 move sonarcloud home page (#362)
authorStas Vilchik <stas.vilchik@sonarsource.com>
Wed, 13 Jun 2018 14:06:41 +0000 (16:06 +0200)
committerSonarTech <sonartech@sonarsource.com>
Thu, 21 Jun 2018 18:21:28 +0000 (20:21 +0200)
20 files changed:
server/sonar-web/public/images/embed-doc/sc-icon.svg [deleted file]
server/sonar-web/public/images/sc-icon.svg [deleted file]
server/sonar-web/public/images/sonarcloud-logo.svg [new file with mode: 0644]
server/sonar-web/public/images/sonarcloud-square-logo.svg [new file with mode: 0644]
server/sonar-web/src/main/js/app/components/GlobalContainer.tsx
server/sonar-web/src/main/js/app/components/Landing.tsx
server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx
server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/EmbedDocsPopup-test.tsx.snap
server/sonar-web/src/main/js/app/theme.js
server/sonar-web/src/main/js/app/utils/startReactApp.js
server/sonar-web/src/main/js/apps/about/components/AboutApp.js
server/sonar-web/src/main/js/apps/about/routes.ts
server/sonar-web/src/main/js/apps/about/sonarcloud/Footer.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/sonarcloud/Home.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/sonarcloud/HomeContainer.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Footer-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Home-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/sonarcloud/style.css [new file with mode: 0644]
server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.tsx
server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginSonarCloud-test.tsx.snap

diff --git a/server/sonar-web/public/images/embed-doc/sc-icon.svg b/server/sonar-web/public/images/embed-doc/sc-icon.svg
deleted file mode 100644 (file)
index bc3d84e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<svg viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M12.625 6.154a3.991 3.991 0 0 0-1.902-1.279v-.046C10.723 2.65 8.93.857 6.75.857c-2.179 0-3.972 1.793-3.972 3.972v.053A3.982 3.982 0 0 0 0 8.671c0 2.179 1.793 3.972 3.972 3.972a3.978 3.978 0 0 0 2.791-1.144 3.97 3.97 0 0 0 2.766 1.122c2.178 0 3.971-1.793 3.971-3.972 0-.905-.31-1.784-.877-2.489l.002-.006zm-3.073 5.489a2.99 2.99 0 0 1-2.973-2.971c0-.275-.225-.5-.5-.5a.501.501 0 0 0-.499.5 3.952 3.952 0 0 0 .56 2.032 2.971 2.971 0 0 1-2.164.936 2.985 2.985 0 0 1-2.97-2.97 2.985 2.985 0 0 1 2.97-2.971c.35 0 .697.062 1.026.183h.012c.114.038.223.09.324.155a.5.5 0 1 0 .65-.759 2.224 2.224 0 0 0-.646-.341 3.974 3.974 0 0 0-1.369-.243h-.192A2.985 2.985 0 0 1 6.75 1.85a2.986 2.986 0 0 1 2.972 2.972c0 .96-.466 1.863-1.249 2.42a.5.5 0 1 0 .58.814 3.983 3.983 0 0 0 1.526-2.184 2.979 2.979 0 0 1 1.941 2.789 2.986 2.986 0 0 1-2.969 2.972l.001.01z" fill="#f3702a" fill-rule="nonzero"/></svg>
\ No newline at end of file
diff --git a/server/sonar-web/public/images/sc-icon.svg b/server/sonar-web/public/images/sc-icon.svg
deleted file mode 100644 (file)
index bc3d84e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<svg viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M12.625 6.154a3.991 3.991 0 0 0-1.902-1.279v-.046C10.723 2.65 8.93.857 6.75.857c-2.179 0-3.972 1.793-3.972 3.972v.053A3.982 3.982 0 0 0 0 8.671c0 2.179 1.793 3.972 3.972 3.972a3.978 3.978 0 0 0 2.791-1.144 3.97 3.97 0 0 0 2.766 1.122c2.178 0 3.971-1.793 3.971-3.972 0-.905-.31-1.784-.877-2.489l.002-.006zm-3.073 5.489a2.99 2.99 0 0 1-2.973-2.971c0-.275-.225-.5-.5-.5a.501.501 0 0 0-.499.5 3.952 3.952 0 0 0 .56 2.032 2.971 2.971 0 0 1-2.164.936 2.985 2.985 0 0 1-2.97-2.97 2.985 2.985 0 0 1 2.97-2.971c.35 0 .697.062 1.026.183h.012c.114.038.223.09.324.155a.5.5 0 1 0 .65-.759 2.224 2.224 0 0 0-.646-.341 3.974 3.974 0 0 0-1.369-.243h-.192A2.985 2.985 0 0 1 6.75 1.85a2.986 2.986 0 0 1 2.972 2.972c0 .96-.466 1.863-1.249 2.42a.5.5 0 1 0 .58.814 3.983 3.983 0 0 0 1.526-2.184 2.979 2.979 0 0 1 1.941 2.789 2.986 2.986 0 0 1-2.969 2.972l.001.01z" fill="#f3702a" fill-rule="nonzero"/></svg>
\ No newline at end of file
diff --git a/server/sonar-web/public/images/sonarcloud-logo.svg b/server/sonar-web/public/images/sonarcloud-logo.svg
new file mode 100644 (file)
index 0000000..afbef3e
--- /dev/null
@@ -0,0 +1 @@
+<svg viewBox="0 0 105 30" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M69.959 19.694c-.42.734-1.346 1.698-2.905 1.698-1.378 0-3.032-.795-3.032-3.999v-5.337h1.596v5.054c0 1.736.509 2.905 1.958 2.905 1.074 0 1.817-.772 2.105-1.506.09-.246.147-.55.147-.85v-5.603h1.596v6.638c0 .94.016 1.772.074 2.492h-1.414l-.088-1.492h-.037zm-36.859.56c-.58.734-1.486 1.133-2.538 1.133-1.797 0-2.87-1.36-2.87-2.83 0-2.393 2.068-3.547 5.21-3.525v-.13c0-.49-.257-1.186-1.618-1.186-.906 0-1.87.32-2.45.696l-.509-1.85c.619-.36 1.833-.81 3.45-.81 2.96 0 3.902 1.812 3.902 3.977v3.204c0 .886.036 1.735.125 2.242h-2.487v.005l-.161-.926H33.1zm-15.716-3.79c0 3.372-2.304 4.923-4.68 4.923-2.597 0-4.593-1.774-4.593-4.755s1.89-4.886 4.738-4.886c2.718.006 4.535 1.948 4.535 4.717zm45.403.075c0 3.373-2.252 4.848-4.373 4.848-2.376 0-4.209-1.812-4.209-4.695 0-3.058 1.922-4.848 4.356-4.848 2.518 0 4.226 1.905 4.226 4.695zm16.675 3.057c-.492 1.017-1.56 1.79-2.996 1.79-2.125 0-3.758-1.866-3.758-4.64-.016-3.036 1.795-4.902 3.937-4.902 1.346 0 2.251.658 2.649 1.399h.036V7.792h1.603v11.032c0 .81.015 1.735.072 2.356h-1.434l-.073-1.584h-.036zm-29.325 1.246c-.419.228-1.346.528-2.524.528-2.649 0-4.37-1.866-4.37-4.657 0-2.812 1.852-4.847 4.716-4.847.943 0 1.78.244 2.215.473l-.361 1.284c-.383-.228-.98-.435-1.854-.435-2.016 0-3.104 1.545-3.104 3.45 0 2.11 1.308 3.41 3.046 3.41.906 0 1.509-.245 1.958-.452l.278 1.246zm-48.69-2.17c.507.32 1.56.696 2.376.696.832 0 1.178-.299 1.178-.772 0-.474-.272-.697-1.309-1.056-1.832-.642-2.54-1.68-2.523-2.775 0-1.712 1.414-3.019 3.613-3.019 1.036 0 1.958.245 2.502.528l-.492 1.98c-.397-.228-1.163-.527-1.922-.527-.67 0-1.052.283-1.052.756 0 .435.345.658 1.435 1.056 1.686.603 2.398 1.49 2.413 2.845 0 1.713-1.309 2.981-3.848 2.981-1.162 0-2.193-.268-2.87-.643l.498-2.05zm19.669 2.519h-2.758v-6.29h.005c0-1.147-.037-2.131-.073-2.943h2.398l.125 1.263h.052a3.224 3.224 0 0 1 2.738-1.47c1.817 0 3.179 1.247 3.179 3.962v5.467h-2.76v-5.108c0-1.187-.397-1.997-1.398-1.997-.764 0-1.215.549-1.397 1.076-.074.169-.111.453-.111.72v5.32zm18.77-.005h-2.76v-6.192c0-1.36-.036-2.246-.072-3.036h2.376l.09 1.698h.073c.455-1.339 1.545-1.904 2.397-1.904.257 0 .383 0 .582.038v2.698a3.76 3.76 0 0 0-.743-.076c-1.017 0-1.708.565-1.89 1.453-.038.19-.054.413-.054.642v4.679zm12.99-.006h-1.597V7.792h1.596V21.18zm2.942-4.543c0 1.997 1.104 3.509 2.67 3.509 1.523 0 2.67-1.49 2.67-3.547 0-1.545-.744-3.508-2.634-3.508s-2.706 1.81-2.706 3.546zm23.517-.87c0-.206-.014-.49-.073-.697-.235-1.055-1.105-1.925-2.304-1.925-1.648 0-2.633 1.506-2.633 3.525 0 1.85.869 3.372 2.597 3.372 1.073 0 2.052-.734 2.34-1.98.053-.229.073-.452.073-.718v-1.577zm-46.344 1.055c-1.45-.016-2.576.337-2.576 1.452 0 .735.471 1.094 1.089 1.094.69 0 1.25-.473 1.435-1.056.036-.152.052-.32.052-.49v-1zm-22.032-.261c0 1.582.634 2.774 1.817 2.774 1.073 0 1.759-1.116 1.759-2.774 0-1.377-.507-2.774-1.76-2.774-1.33 0-1.816 1.413-1.816 2.774z" fill="#fff" fill-rule="nonzero"/><path d="M102.86 13.634a4.959 4.959 0 0 0-2.363-1.649v-.06c0-2.823-2.208-5.124-4.93-5.124-2.724 0-4.933 2.296-4.933 5.125v.07c-1.994.653-3.45 2.595-3.45 4.886 0 2.823 2.21 5.125 4.932 5.125a4.832 4.832 0 0 0 3.465-1.475 4.817 4.817 0 0 0 3.461 1.475c2.717 0 4.933-2.296 4.933-5.125 0-1.18-.4-2.334-1.115-3.248zm-3.818 7.077c-2.031 0-3.685-1.718-3.685-3.83a.637.637 0 0 0-.623-.646.634.634 0 0 0-.624.647c0 .957.257 1.855.696 2.622a3.607 3.607 0 0 1-2.69 1.213c-2.032 0-3.687-1.719-3.687-3.83 0-2.11 1.655-3.829 3.687-3.829.44 0 .868.082 1.278.234.005 0 .009.005.014.005.142.05.342.147.404.201a.6.6 0 0 0 .874-.07.659.659 0 0 0-.068-.91c-.272-.239-.696-.402-.8-.44a4.767 4.767 0 0 0-1.697-.31c-.079 0-.157 0-.236.005.084-2.04 1.702-3.671 3.687-3.671 2.031 0 3.685 1.718 3.685 3.83a3.896 3.896 0 0 1-1.55 3.122.663.663 0 0 0-.147.898c.12.174.315.272.509.272.125 0 .25-.038.361-.12a5.164 5.164 0 0 0 1.895-2.812c1.424.549 2.413 1.979 2.413 3.595-.005 2.106-1.659 3.824-3.696 3.824z" fill="#f60" fill-rule="nonzero"/></svg>
diff --git a/server/sonar-web/public/images/sonarcloud-square-logo.svg b/server/sonar-web/public/images/sonarcloud-square-logo.svg
new file mode 100644 (file)
index 0000000..bc3d84e
--- /dev/null
@@ -0,0 +1 @@
+<svg viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M12.625 6.154a3.991 3.991 0 0 0-1.902-1.279v-.046C10.723 2.65 8.93.857 6.75.857c-2.179 0-3.972 1.793-3.972 3.972v.053A3.982 3.982 0 0 0 0 8.671c0 2.179 1.793 3.972 3.972 3.972a3.978 3.978 0 0 0 2.791-1.144 3.97 3.97 0 0 0 2.766 1.122c2.178 0 3.971-1.793 3.971-3.972 0-.905-.31-1.784-.877-2.489l.002-.006zm-3.073 5.489a2.99 2.99 0 0 1-2.973-2.971c0-.275-.225-.5-.5-.5a.501.501 0 0 0-.499.5 3.952 3.952 0 0 0 .56 2.032 2.971 2.971 0 0 1-2.164.936 2.985 2.985 0 0 1-2.97-2.97 2.985 2.985 0 0 1 2.97-2.971c.35 0 .697.062 1.026.183h.012c.114.038.223.09.324.155a.5.5 0 1 0 .65-.759 2.224 2.224 0 0 0-.646-.341 3.974 3.974 0 0 0-1.369-.243h-.192A2.985 2.985 0 0 1 6.75 1.85a2.986 2.986 0 0 1 2.972 2.972c0 .96-.466 1.863-1.249 2.42a.5.5 0 1 0 .58.814 3.983 3.983 0 0 0 1.526-2.184 2.979 2.979 0 0 1 1.941 2.789 2.986 2.986 0 0 1-2.969 2.972l.001.01z" fill="#f3702a" fill-rule="nonzero"/></svg>
\ No newline at end of file
index c8b7167640e36f551944283d28b359e6eeefbeb2..d924a697abf4bf3958cafea3f8089ca93932de9d 100644 (file)
@@ -27,11 +27,13 @@ import Workspace from '../../components/workspace/Workspace';
 
 interface Props {
   children: React.ReactNode;
+  footer?: React.ReactNode;
   location: { pathname: string };
 }
 
 export default function GlobalContainer(props: Props) {
   // it is important to pass `location` down to `GlobalNav` to trigger render on url change
+  const { footer = <GlobalFooterContainer /> } = props;
   return (
     <SuggestionsProvider>
       {({ suggestions }) => (
@@ -46,7 +48,7 @@ export default function GlobalContainer(props: Props) {
                 </Workspace>
               </div>
             </div>
-            <GlobalFooterContainer />
+            {footer}
           </div>
         </StartupModal>
       )}
index 55f14b6056d6d4611d33843cdabf038e96fbff7e..d4f80be9ab820d96caff8d2e6573158c4a06e62a 100644 (file)
 import * as React from 'react';
 import * as PropTypes from 'prop-types';
 import { connect } from 'react-redux';
+import { Location } from 'history';
 import { CurrentUser, isLoggedIn } from '../types';
 import { getCurrentUser } from '../../store/rootReducer';
 import { getHomePageUrl } from '../../helpers/urls';
-import { isSonarCloud } from '../../helpers/system';
 
-interface Props {
+interface StateProps {
   currentUser: CurrentUser | undefined;
 }
 
-class Landing extends React.PureComponent<Props> {
+interface OwnProps {
+  location: Location;
+}
+
+class Landing extends React.PureComponent<StateProps & OwnProps> {
   static contextTypes = {
     router: PropTypes.object.isRequired
   };
@@ -43,8 +47,6 @@ class Landing extends React.PureComponent<Props> {
       } else {
         this.context.router.replace('/projects');
       }
-    } else if (isSonarCloud()) {
-      window.location.href = 'https://about.sonarcloud.io';
     } else {
       this.context.router.replace('/about');
     }
@@ -59,4 +61,4 @@ const mapStateToProps = (state: any) => ({
   currentUser: getCurrentUser(state)
 });
 
-export default connect<Props>(mapStateToProps)(Landing);
+export default connect<StateProps, {}, OwnProps>(mapStateToProps)(Landing);
index cbaea65d18cefa2bc08aea060d8ebcedb56e0721..061a3af556b611debc20a18565c1a0c9a394a785 100644 (file)
@@ -75,7 +75,7 @@ export default class EmbedDocsPopup extends React.PureComponent<Props> {
           alt={text}
           className="spacer-right"
           height="18"
-          src={`${getBaseUrl()}/images/embed-doc/${icon}`}
+          src={`${getBaseUrl()}/images/${icon}`}
           width="18"
         />
         {text}
@@ -98,12 +98,16 @@ export default class EmbedDocsPopup extends React.PureComponent<Props> {
         <li className="divider" />
         {this.renderTitle(translate('embed_docs.stay_connected'))}
         <li>
-          {this.renderIconLink('https://twitter.com/sonarcloud', 'twitter-icon.svg', 'Twitter')}
+          {this.renderIconLink(
+            'https://twitter.com/sonarcloud',
+            'embed-doc/twitter-icon.svg',
+            'Twitter'
+          )}
         </li>
         <li>
           {this.renderIconLink(
             'https://blog.sonarsource.com/product/SonarCloud',
-            'sc-icon.svg',
+            'sonarcloud-square-logo.svg',
             translate('embed_docs.news')
           )}
         </li>
@@ -135,12 +139,16 @@ export default class EmbedDocsPopup extends React.PureComponent<Props> {
         <li>
           {this.renderIconLink(
             'https://www.sonarsource.com/resources/product-news/',
-            'sq-icon.svg',
+            'embed-doc/sq-icon.svg',
             translate('embed_docs.news')
           )}
         </li>
         <li>
-          {this.renderIconLink('https://twitter.com/SonarQube', 'twitter-icon.svg', 'Twitter')}
+          {this.renderIconLink(
+            'https://twitter.com/SonarQube',
+            'embed-doc/twitter-icon.svg',
+            'Twitter'
+          )}
         </li>
       </React.Fragment>
     );
index 3fc1cca678d4e597ddbef9e2fe8d84a400e6860b..c324ca11c23c193eb6c0d08f808977ad3d7c6da5 100644 (file)
@@ -106,7 +106,7 @@ exports[`should display correct links for SonarCloud 1`] = `
             alt="embed_docs.news"
             className="spacer-right"
             height="18"
-            src="/images/embed-doc/sc-icon.svg"
+            src="/images/sonarcloud-square-logo.svg"
             width="18"
           />
           embed_docs.news
index e57fc075f6c14e65818552c55ee595664af68abd..76560dcf9857ca4c58c3f3a09b9fd4a99faa8467 100644 (file)
@@ -106,5 +106,14 @@ module.exports = {
   modalZIndex: '6001',
   modalOverlayZIndex: '6000',
 
-  popupZIndex: '5000'
+  popupZIndex: '5000',
+
+  // sonarcloud
+  sonarcloudOrange: '#f60',
+  sonarcloudOrangeDark: '#e65c00',
+  sonarcloudFontFamily:
+    "Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif",
+  sonarcloudBlack300: '#cfd3d7',
+  sonarcloudBlack700: '#434447',
+  sonarcloudBlack800: '#2d3032'
 };
index 611b8a238d1411309f1a5b8c81139f4b0f8b292c..b4b79feec06a939ce527f201e935ff13064f49e1 100644 (file)
@@ -153,9 +153,9 @@ const startReactApp = () => {
 
             <Route path="/" component={App}>
               <IndexRoute component={lazyLoad(() => import('../components/Landing'))} />
+              <Route path="about" childRoutes={aboutRoutes} />
 
               <Route component={GlobalContainer}>
-                <Route path="about" childRoutes={aboutRoutes} />
                 <Route path="account" childRoutes={accountRoutes} />
                 <Route path="coding_rules" childRoutes={codingRulesRoutes} />
                 <Route path="component" childRoutes={componentRoutes} />
index 9074488497c8cc9b26148715fedfc52239493758..5221f845d5d0ef161f6f0bf8028ef73038ef8653 100644 (file)
@@ -33,6 +33,7 @@ import AboutStandards from './AboutStandards';
 import AboutScanners from './AboutScanners';
 import { searchProjects } from '../../../api/components';
 import { getFacet } from '../../../api/issues';
+import GlobalContainer from '../../../app/components/GlobalContainer';
 import { getAppState, getCurrentUser, getGlobalSettingValue } from '../../../store/rootReducer';
 import { translate } from '../../../helpers/l10n';
 import { fetchAboutPageSettings } from '../actions';
@@ -61,7 +62,8 @@ class AboutApp extends React.PureComponent {
     },
     currentUser: { isLoggedIn: boolean },
     customText?: string,
-    fetchAboutPageSettings: () => Promise<*>
+    fetchAboutPageSettings: () => Promise<*>,
+    location: { pathname: string }
   };
 */
 
@@ -142,67 +144,69 @@ class AboutApp extends React.PureComponent {
     }
 
     return (
-      <div className="page page-limited about-page" id="about-page">
-        <div className="about-page-entry">
-          <div className="about-page-intro">
-            <h1 className="big-spacer-bottom">{translate('layout.sonar.slogan')}</h1>
-            {!this.props.currentUser.isLoggedIn && (
-              <Link className="button button-active big-spacer-right" to="/sessions/new">
-                {translate('layout.login')}
-              </Link>
-            )}
-            <a
-              className="button"
-              href="https://redirect.sonarsource.com/doc/home.html"
-              rel="noopener noreferrer"
-              target="_blank">
-              {translate('about_page.read_documentation')}
-            </a>
+      <GlobalContainer location={this.props.location}>
+        <div className="page page-limited about-page" id="about-page">
+          <div className="about-page-entry">
+            <div className="about-page-intro">
+              <h1 className="big-spacer-bottom">{translate('layout.sonar.slogan')}</h1>
+              {!this.props.currentUser.isLoggedIn && (
+                <Link className="button button-active big-spacer-right" to="/sessions/new">
+                  {translate('layout.login')}
+                </Link>
+              )}
+              <a
+                className="button"
+                href="https://redirect.sonarsource.com/doc/home.html"
+                rel="noopener noreferrer"
+                target="_blank">
+                {translate('about_page.read_documentation')}
+              </a>
+            </div>
+
+            <div className="about-page-instance">
+              <AboutProjects count={projectsCount} loading={loading} />
+              <EntryIssueTypes
+                bugs={bugs}
+                codeSmells={codeSmells}
+                loading={loading}
+                vulnerabilities={vulnerabilities}
+              />
+            </div>
           </div>
 
-          <div className="about-page-instance">
-            <AboutProjects count={projectsCount} loading={loading} />
-            <EntryIssueTypes
-              bugs={bugs}
-              codeSmells={codeSmells}
-              loading={loading}
-              vulnerabilities={vulnerabilities}
-            />
-          </div>
-        </div>
-
-        {customText != null &&
-          customText.value && (
-            <div
-              className="about-page-section"
-              dangerouslySetInnerHTML={{ __html: customText.value }}
-            />
-          )}
+          {customText != null &&
+            customText.value && (
+              <div
+                className="about-page-section"
+                dangerouslySetInnerHTML={{ __html: customText.value }}
+              />
+            )}
 
-        <AboutLanguages />
+          <AboutLanguages />
 
-        <AboutQualityModel />
+          <AboutQualityModel />
 
-        <div className="flex-columns">
-          <div className="flex-column flex-column-half about-page-group-boxes">
-            <AboutCleanCode />
+          <div className="flex-columns">
+            <div className="flex-column flex-column-half about-page-group-boxes">
+              <AboutCleanCode />
+            </div>
+            <div className="flex-column flex-column-half about-page-group-boxes">
+              <AboutLeakPeriod />
+            </div>
           </div>
-          <div className="flex-column flex-column-half about-page-group-boxes">
-            <AboutLeakPeriod />
-          </div>
-        </div>
 
-        <div className="flex-columns">
-          <div className="flex-column flex-column-half about-page-group-boxes">
-            <AboutQualityGates />
-          </div>
-          <div className="flex-column flex-column-half about-page-group-boxes">
-            <AboutStandards appState={this.props.appState} />
+          <div className="flex-columns">
+            <div className="flex-column flex-column-half about-page-group-boxes">
+              <AboutQualityGates />
+            </div>
+            <div className="flex-column flex-column-half about-page-group-boxes">
+              <AboutStandards appState={this.props.appState} />
+            </div>
           </div>
-        </div>
 
-        <AboutScanners />
-      </div>
+          <AboutScanners />
+        </div>
+      </GlobalContainer>
     );
   }
 }
index 6d586df600f29412e8d98bb9c071ab41e8e1eeec..ad8591fc26a8b3213b04a31185763a59cabc3743 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import { lazyLoad } from '../../components/lazyLoad';
+import { isSonarCloud } from '../../helpers/system';
 
 const routes = [
   {
-    indexRoute: { component: lazyLoad(() => import('./components/AboutApp')) }
+    indexRoute: {
+      component: lazyLoad(
+        () =>
+          isSonarCloud() ? import('./sonarcloud/HomeContainer') : import('./components/AboutApp')
+      )
+    }
   }
 ];
 
diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/Footer.tsx b/server/sonar-web/src/main/js/apps/about/sonarcloud/Footer.tsx
new file mode 100644 (file)
index 0000000..48cd48d
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import * as React from 'react';
+import { Link } from 'react-router';
+import { getBaseUrl } from '../../../helpers/urls';
+
+export default function Footer() {
+  return (
+    <footer className="sc-footer">
+      <div className="sc-footer-limited">
+        <nav className="sc-footer-nav">
+          <div className="sc-footer-nav-column">
+            <h4 className="sc-footer-nav-column-title">Need Help</h4>
+            <ul>
+              <li className="spacer-top">
+                <a
+                  className="sc-footer-link"
+                  href="https://community.sonarsource.com/c/help/sc"
+                  rel="noopener noreferrer"
+                  target="_blank">
+                  Support Forum
+                </a>
+              </li>
+              <li className="spacer-top">
+                <Link
+                  className="sc-footer-link"
+                  rel="noopener noreferrer"
+                  target="_blank"
+                  to="/contact">
+                  Contact Us
+                </Link>
+              </li>
+              <li className="spacer-top">
+                <a
+                  className="sc-footer-link"
+                  href="https://sonarcloud.statuspage.io/"
+                  rel="noopener noreferrer"
+                  target="_blank">
+                  Status
+                </a>
+              </li>
+            </ul>
+          </div>
+          <div className="sc-footer-nav-column">
+            <h4 className="sc-footer-nav-column-title">News</h4>
+            <ul>
+              <li className="spacer-top">
+                <a
+                  className="sc-footer-link"
+                  href="https://blog.sonarsource.com/product/SonarCloud"
+                  rel="noopener noreferrer"
+                  target="_blank">
+                  SonarCloud News
+                </a>
+              </li>
+              <li className="spacer-top">
+                <a
+                  className="sc-footer-link"
+                  href="https://twitter.com/sonarcloud"
+                  rel="noopener noreferrer"
+                  target="_blank">
+                  Twitter
+                </a>
+              </li>
+            </ul>
+          </div>
+          <div className="sc-footer-nav-column">
+            <h4 className="sc-footer-nav-column-title">About</h4>
+            <ul>
+              <li className="spacer-top">
+                <a
+                  className="sc-footer-link"
+                  href="https://www.sonarsource.com/"
+                  rel="noopener noreferrer"
+                  target="_blank">
+                  SonarSource
+                </a>
+              </li>
+              <li className="spacer-top">
+                <Link
+                  className="sc-footer-link"
+                  download="terms.pdf"
+                  rel="noopener noreferrer"
+                  target="_blank"
+                  to="/terms.pdf">
+                  Terms
+                </Link>
+              </li>
+              <li className="spacer-top">
+                <Link
+                  className="sc-footer-link"
+                  rel="noopener noreferrer"
+                  target="_blank"
+                  to="/privacy">
+                  Privacy
+                </Link>
+              </li>
+            </ul>
+          </div>
+        </nav>
+
+        <div className="sc-footer-logo">
+          <Link className="display-inline-block link-no-underline" to="/">
+            <img alt="SonarCloud" height="45" src={`${getBaseUrl()}/images/sonarcloud-logo.svg`} />
+          </Link>
+          <div>
+            <a
+              className="sc-footer-link"
+              href="https://www.sonarsource.com"
+              rel="noopener noreferrer"
+              target="_blank">
+              A SonarSource™ product
+            </a>
+          </div>
+        </div>
+      </div>
+
+      <div className="sc-footer-copy">
+        <div className="sc-footer-limited">
+          © 2008-2018, SonarCloud by{' '}
+          <a
+            className="sc-footer-link sc-footer-copy-link"
+            href="https://www.sonarsource.com"
+            rel="noopener noreferrer"
+            target="_blank">
+            SonarSource SA
+          </a>. All rights reserved. SonarCloud is a service operated by{' '}
+          <a
+            className="sc-footer-link sc-footer-copy-link"
+            href="https://www.sonarsource.com"
+            rel="noopener noreferrer"
+            target="_blank">
+            SonarSource
+          </a>, the company that develops and promotes open source{' '}
+          <a
+            className="sc-footer-link sc-footer-copy-link"
+            href="http://sonarqube.org"
+            rel="noopener noreferrer"
+            target="_blank">
+            SonarQube
+          </a>{' '}
+          and{' '}
+          <a
+            className="sc-footer-link sc-footer-copy-link"
+            href="http://sonarlint.org"
+            rel="noopener noreferrer"
+            target="_blank">
+            SonarLint
+          </a>.
+        </div>
+      </div>
+    </footer>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/Home.tsx b/server/sonar-web/src/main/js/apps/about/sonarcloud/Home.tsx
new file mode 100644 (file)
index 0000000..5118ad3
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import * as React from 'react';
+import { Link } from 'react-router';
+import Footer from './Footer';
+import GlobalContainer from '../../../app/components/GlobalContainer';
+import { CurrentUser, isLoggedIn } from '../../../app/types';
+import ChevronRightIcon from '../../../components/icons-components/ChevronRightcon';
+import './style.css';
+
+interface Props {
+  currentUser: CurrentUser;
+  location: { pathname: string };
+}
+
+export default class Home extends React.PureComponent<Props> {
+  componentDidMount() {
+    document.documentElement.classList.add('white-page');
+    document.body.classList.add('white-page');
+  }
+
+  componentWillUnmount() {
+    document.documentElement.classList.remove('white-page');
+    document.body.classList.remove('white-page');
+  }
+
+  render() {
+    return (
+      <GlobalContainer footer={<Footer />} location={this.props.location}>
+        <div className="page page-limited sc-page">
+          <h1 className="sc-page-title">Continuous Code Quality Online</h1>
+          <p className="sc-page-subtitle">
+            Analyze the quality of your source code to detect bugs, vulnerabilities <br />and code
+            smells throughout the development process.
+          </p>
+
+          <ul className="sc-features-list">
+            <li className="sc-feature">
+              <h2 className="sc-feature-title">Built on SonarQube</h2>
+              <p className="sc-feature-description">
+                The broadly used code review tool to detect bugs, code smells and vulnerability
+                issues.
+              </p>
+            </li>
+
+            <li className="sc-feature">
+              <h2 className="sc-feature-title">17 languages</h2>
+              <p className="sc-feature-description">
+                Java, JS, C#, C/C++, Objective-C, TypeScript, Python, Go, ABAP, PL/SQL, T-SQL and
+                more.
+              </p>
+            </li>
+
+            <li className="sc-feature">
+              <h2 className="sc-feature-title">Thousands of rules</h2>
+              <p className="sc-feature-description">
+                Track down hard-to-find bugs and quality issues thanks to powerful static code
+                analyzers.
+              </p>
+            </li>
+
+            <li className="sc-feature">
+              <h2 className="sc-feature-title">Cloud CI Integrations</h2>
+              <p className="sc-feature-description">
+                Schedule the execution of an analysis from Cloud CI engines: Travis, VSTS, AppVeyor
+                and more.
+              </p>
+            </li>
+
+            <li className="sc-feature">
+              <h2 className="sc-feature-title">Deep code analysis</h2>
+              <p className="sc-feature-description">
+                Explore all your source files, whether in branches or pull requests, to reach a
+                green quality gate and promote the build.
+              </p>
+            </li>
+
+            <li className="sc-feature">
+              <h2 className="sc-feature-title">Fast and Scalable</h2>
+              <p className="sc-feature-description">Scale on-demand as your projects grow.</p>
+            </li>
+          </ul>
+
+          <div className="sc-pricing sc-narrow-container">
+            <div className="sc-pricing-block">
+              <h3 className="sc-pricing-title">Open Source Projects</h3>
+              <span className="sc-pricing-small">&nbsp;</span>
+              <span className="sc-pricing-price">Free</span>
+            </div>
+
+            <div className="sc-pricing-block">
+              <h3 className="sc-pricing-title">Private Projects</h3>
+              <span className="sc-pricing-small">14 days free trial</span>
+              <strong>
+                From <span className="sc-pricing-price">10€</span>/mo
+              </strong>
+              <Link
+                className="sc-pricing-about sc-pricing-small"
+                to="/documentation/sonarcloud-pricing">
+                see prices
+              </Link>
+            </div>
+          </div>
+
+          {!isLoggedIn(this.props.currentUser) && (
+            <div className="sc-narrow-container text-center">
+              <Link className="sc-start" to="/sessions/new">
+                Start using SonarCloud <ChevronRightIcon className="spacer-left" />
+              </Link>
+              <div className="big-spacer-top">
+                <a
+                  className="text-muted"
+                  href="https://community.sonarsource.com/c/help/sc"
+                  rel="noopener noreferrer"
+                  target="_blank">
+                  Need help?
+                </a>
+              </div>
+            </div>
+          )}
+
+          <div className="sc-narrow-container text-center">
+            <h2 className="sc-feature-title">Explore open source projects on SonarCloud</h2>
+            <p className="sc-feature-description">
+              SonarCloud offers free analysis for open source projects. <br />It is public and open
+              to anyone who wants to browse the service.
+            </p>
+          </div>
+
+          <div className="sc-narrow-container text-center">
+            <Link className="sc-browse" to="/explore/projects">
+              Browse
+            </Link>
+          </div>
+
+          <div className="sc-narrow-container sc-news">
+            <h2 className="sc-news-title">News</h2>
+            <ChevronRightIcon className="big-spacer-left" fill="#cfd3d7" />
+            <a
+              className="sc-news-link big-spacer-left"
+              href="http://feedburner.google.com/fb/a/mailverify?uri=NewsSonarCloud&loc=en_US"
+              rel="noopener noreferrer"
+              target="_blank">
+              Subscribe by email
+            </a>
+            <a
+              className="sc-news-link big-spacer-left"
+              href="http://feeds.feedburner.com/NewsSonarCloud"
+              rel="noopener noreferrer"
+              target="_blank">
+              Subscribe by feed
+            </a>
+            <a
+              className="sc-news-link big-spacer-left"
+              href="https://blog.sonarsource.com/product/SonarCloud"
+              rel="noopener noreferrer"
+              target="_blank">
+              See all
+            </a>
+          </div>
+        </div>
+      </GlobalContainer>
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/HomeContainer.tsx b/server/sonar-web/src/main/js/apps/about/sonarcloud/HomeContainer.tsx
new file mode 100644 (file)
index 0000000..3fc2153
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import { connect } from 'react-redux';
+import Home from './Home';
+import { getCurrentUser } from '../../../store/rootReducer';
+
+const mapStateToProps = (state: any) => ({
+  currentUser: getCurrentUser(state)
+});
+
+export default connect(mapStateToProps)(Home);
diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Footer-test.tsx b/server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Footer-test.tsx
new file mode 100644 (file)
index 0000000..0d1eb66
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import * as React from 'react';
+import { shallow } from 'enzyme';
+import Footer from '../Footer';
+
+it('should render', () => {
+  expect(shallow(<Footer />)).toBeDefined();
+});
diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Home-test.tsx b/server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Home-test.tsx
new file mode 100644 (file)
index 0000000..9c5caa9
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import * as React from 'react';
+import { shallow } from 'enzyme';
+import Home from '../Home';
+
+jest.mock('Docs/EmbedDocsSuggestions.json', () => ({}), { virtual: true });
+
+it('should render', () => {
+  expect(
+    shallow(<Home currentUser={{ isLoggedIn: false }} location={{ pathname: '/' }} />)
+  ).toBeDefined();
+});
+
+it('should not render "Start using SonarCloud" button', () => {
+  expect(
+    shallow(<Home currentUser={{ isLoggedIn: true }} location={{ pathname: '/' }} />)
+      .find('.sc-start')
+      .exists()
+  ).toBe(false);
+});
diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/style.css b/server/sonar-web/src/main/js/apps/about/sonarcloud/style.css
new file mode 100644 (file)
index 0000000..711ee61
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,700');
+
+.sc-page {
+  font-family: var(--sonarcloudFontFamily);
+}
+
+.sc-page *:focus,
+.sc-footer *:focus {
+  box-shadow: 0 0 0 3px rgba(230, 92, 0, 0.25);
+}
+
+.sc-page-title {
+  line-height: 56px;
+  margin-top: 40px;
+  margin-bottom: 20px;
+  font-size: 40px;
+  font-weight: 300;
+  text-align: center;
+}
+
+.sc-page-subtitle {
+  line-height: 28px;
+  margin-bottom: 40px;
+  font-size: 20px;
+  font-weight: 300;
+  text-align: center;
+}
+
+.sc-features-list {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+}
+
+.sc-feature {
+  width: 30%;
+  margin-bottom: 30px;
+}
+
+.sc-feature-title {
+  line-height: 28px;
+  margin-bottom: 5px;
+  font-size: 20px;
+  font-weight: 400;
+}
+
+.sc-feature-description {
+  line-height: 22px;
+  font-size: 16px;
+  font-weight: 300;
+}
+
+.sc-narrow-container {
+  width: 700px;
+  margin: 40px auto;
+}
+
+.sc-pricing {
+  display: flex;
+  justify-content: space-between;
+}
+
+.sc-pricing-block {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  width: 330px;
+  padding: 20px 20px 30px;
+  border: 1px solid var(--sonarcloudBlack300);
+  border-radius: 10px;
+  box-sizing: border-box;
+  line-height: 20px;
+  font-size: 16px;
+}
+
+.sc-pricing-title {
+  line-height: 34px;
+  margin-bottom: 20px;
+  color: var(--sonarcloudOrange);
+  font-size: 24px;
+  font-weight: 400;
+}
+
+.sc-pricing-price {
+  line-height: 72px;
+  font-size: 65px;
+  font-weight: 700;
+}
+
+.sc-pricing-small {
+  font-size: 14px;
+}
+
+.sc-pricing-about {
+  position: relative;
+  border: none;
+  color: var(--baseFontColor);
+}
+
+.sc-pricing-about::after {
+  content: '→';
+  position: absolute;
+  top: 0;
+  left: calc(100% + 5px);
+  transition: left 0.3s ease;
+}
+
+.sc-pricing-about:hover {
+  color: var(--baseFontColor);
+}
+
+.sc-pricing-about:focus {
+  color: var(--sonarcloudOrange);
+}
+
+.sc-pricing-about:hover::after {
+  left: calc(100% + 10px);
+}
+
+.sc-start {
+  display: inline-flex;
+  align-items: center;
+  height: 44px;
+  line-height: 44px;
+  padding: 0 16px;
+  border-radius: 5px;
+  border: none;
+  color: #fff;
+  font-size: 16px;
+  font-weight: 700;
+  background-color: var(--sonarcloudOrange);
+}
+
+.sc-start:hover,
+.sc-start:focus {
+  background-color: var(--sonarcloudOrangeDark);
+  color: #fff;
+}
+
+.sc-browse {
+  display: inline-flex;
+  align-items: center;
+  height: 33px;
+  line-height: 33px;
+  padding: 0 16px;
+  border-radius: 5px;
+  border: 1px solid var(--sonarcloudOrange);
+  box-sizing: border-box;
+  color: var(--sonarcloudOrange);
+  font-size: 16px;
+  font-weight: 700;
+  transition: box-shadow 0.3s ease;
+}
+
+.sc-browse:hover,
+.sc-browse:focus {
+  background-color: var(--sonarcloudOrange);
+  color: #fff;
+}
+
+.sc-news {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border-top: 1px solid var(--sonarcloudBlack300);
+  padding-top: 32px;
+}
+
+.sc-news-title {
+  display: inline-block;
+  font-size: 18px;
+}
+
+.sc-news-link {
+  border-bottom-color: var(--sonarcloudBlack300);
+  color: var(--baseFontColor);
+}
+
+.sc-news-link:hover,
+.sc-news-link:focus {
+  border-bottom-color: var(--sonarcloudOrange);
+  color: var(--sonarcloudOrange);
+}
+
+.sc-footer {
+  background-color: var(--sonarcloudBlack800);
+  color: var(--sonarcloudBlack300);
+  font-size: 12px;
+}
+
+.sc-footer-limited {
+  position: relative;
+  max-width: 1280px;
+  margin-left: auto;
+  margin-right: auto;
+  padding-left: 20px;
+  padding-right: 20px;
+}
+
+.sc-footer-copy {
+  padding: 20px 0;
+  border-top: 1px solid var(--sonarcloudBlack700);
+  line-height: 16px;
+  font-size: 11px;
+  text-align: center;
+}
+
+.sc-footer-copy-link {
+  text-decoration: underline;
+}
+
+.sc-footer-nav {
+  display: flex;
+  padding: 30px 0;
+}
+
+.sc-footer-nav-column {
+  margin-right: 60px;
+}
+
+.sc-footer-nav-column-title {
+  line-height: 1;
+  margin-bottom: 16px;
+  color: #fff;
+  font-size: 12px;
+  font-weight: 700;
+  text-transform: uppercase;
+}
+
+.sc-footer-link {
+  border: none;
+  color: inherit;
+}
+
+.sc-footer-link:hover {
+  color: #fff;
+}
+
+.sc-footer-link:focus {
+  color: var(--sonarcloudOrange);
+}
+
+.sc-footer-logo {
+  position: absolute;
+  top: 30px;
+  right: 20px;
+}
index 80843135a5debeb7f32b2ae40697c339a46b8be4..8aa620c9acefa13fb1a4d5623419b5003e230063 100644 (file)
@@ -22,7 +22,7 @@ import * as classNames from 'classnames';
 import LoginForm from './LoginForm';
 import OAuthProviders from './OAuthProviders';
 import { IdentityProvider } from '../../../app/types';
-import { getHostUrl } from '../../../helpers/urls';
+import { getBaseUrl } from '../../../helpers/urls';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import './LoginSonarCloud.css';
 
@@ -50,7 +50,7 @@ export default function LoginSonarCloud({
         <img
           alt="SonarCloud logo"
           height={36}
-          src={`${getHostUrl()}/images/sc-icon.svg`}
+          src={`${getBaseUrl()}/images/sonarcloud-square-logo.svg`}
           width={36}
         />
         <h1 className="sonarcloud-login-title">
index 7a2921af8dde14728959011a9262cf1dd837c6b4..cd3b0f00ea8e063a992600e4c970f2ac9afd3ac4 100644 (file)
@@ -11,7 +11,7 @@ exports[`logs in with identity provider 1`] = `
     <img
       alt="SonarCloud logo"
       height={36}
-      src="null/images/sc-icon.svg"
+      src="/images/sonarcloud-square-logo.svg"
       width={36}
     />
     <h1
@@ -49,7 +49,7 @@ exports[`logs in with simple form 1`] = `
     <img
       alt="SonarCloud logo"
       height={36}
-      src="null/images/sc-icon.svg"
+      src="/images/sonarcloud-square-logo.svg"
       width={36}
     />
     <h1
@@ -76,7 +76,7 @@ exports[`logs in with simple form 2`] = `
     <img
       alt="SonarCloud logo"
       height={36}
-      src="null/images/sc-icon.svg"
+      src="/images/sonarcloud-square-logo.svg"
       width={36}
     />
     <h1