diff --git a/.babelrc b/.babelrc
index b02645ca1..eb6d32d93 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,5 +1,5 @@
{
- "presets": ["@babel/preset-env", "@babel/preset-react"],
+ "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"],
"plugins": [
["babel-plugin-wildcard", { "exts": ["json"], "nostrip": true, "noModifyCase": true }],
[
diff --git a/.dockerignore b/.dockerignore
index 0634d58ed..990a864bc 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -4,7 +4,6 @@
.vscode
.eslintrc.yml
.gitignore
-.sass-lint.yml
.travis.yml
node_modules
diff --git a/.gitignore b/.gitignore
index 8a30e37c5..c329861ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,6 @@
*.swp
*.vi
*~
-*.sass-cache
# OS or Editor folders
.DS_Store
diff --git a/.sass-lint.yml b/.sass-lint.yml
deleted file mode 100644
index 110a25ab8..000000000
--- a/.sass-lint.yml
+++ /dev/null
@@ -1,95 +0,0 @@
-options:
- formatter: stylish
-files:
- include: '**/*.s+(a|c)ss'
-rules:
- # Extends
- extends-before-mixins: 1
- extends-before-declarations: 1
- placeholder-in-extend: 1
-
- # Mixins
- mixins-before-declarations: 1
-
- # Line Spacing
- one-declaration-per-line: 1
- empty-line-between-blocks: 1
- single-line-per-selector: 1
-
- # Disallows
- no-attribute-selectors: 0
- no-color-hex: 0
- no-color-keywords: 1
- no-color-literals: 1
- no-combinators: 0
- no-css-comments: 1
- no-debug: 1
- no-disallowed-properties: 0
- no-duplicate-properties: 1
- no-empty-rulesets: 1
- no-extends: 0
- no-ids: 1
- no-important: 1
- no-invalid-hex: 1
- no-mergeable-selectors: 1
- no-misspelled-properties: 1
- no-qualifying-elements: 1
- no-trailing-whitespace: 1
- no-trailing-zero: 1
- no-transition-all: 1
- no-universal-selectors: 0
- no-url-domains: 1
- no-url-protocols: 1
- no-vendor-prefixes: 1
- no-warn: 1
- property-units: 0
-
- # Nesting
- declarations-before-nesting: 1
- force-attribute-nesting: 1
- force-element-nesting: 1
- force-pseudo-nesting: 1
-
- # Name Formats
- class-name-format: 1
- function-name-format: 1
- id-name-format: 0
- mixin-name-format: 1
- placeholder-name-format: 1
- variable-name-format: 1
-
- # Style Guide
- attribute-quotes: 1
- bem-depth: 0
- border-zero: 1
- brace-style: 1
- clean-import-paths: 1
- empty-args: 1
- hex-length: 1
- hex-notation: 1
- indentation: 1
- leading-zero: 0
- max-line-length: 0
- max-file-line-count: 0
- nesting-depth: 1
- property-sort-order: 0
- pseudo-element: 1
- quotes: 1
- shorthand-values: 1
- url-quotes: 1
- variable-for-property: 1
- zero-unit: 1
-
- # Inner Spacing
- space-after-comma: 1
- space-before-colon: 1
- space-after-colon: 1
- space-before-brace: 1
- space-before-bang: 1
- space-after-bang: 1
- space-between-parens: 1
- space-around-operator: 1
-
- # Final Items
- trailing-semicolon: 1
- final-newline: 1
diff --git a/README.md b/README.md
index 860dc26d4..a1ce2eb25 100644
--- a/README.md
+++ b/README.md
@@ -59,7 +59,6 @@ app
│ │ └── selectors.js => Re-select selectors to select data in state
│ └── ...
├── static => Static assets, directly copied to the public directory
-├── styles => Stylesheets in .sass format, all included from application.sass
└── router.jsx => Application router and main entry point
```
diff --git a/app/API/no_internet_error.js b/app/API/no_internet_error.js
index 9aaf4ae20..137fe4633 100644
--- a/app/API/no_internet_error.js
+++ b/app/API/no_internet_error.js
@@ -1,14 +1,14 @@
// Used only to show a message when request fail / timeout due to connection problems
+
import { NO_INTERNET_ERROR } from '../constants'
import { flashError } from '../state/flashes/reducer'
-import store from '../state/index'
export default function noInternetError() {
- store.dispatch(
- flashError({
- message: NO_INTERNET_ERROR,
- timeLeft: 999999999999,
- infoText: 'actions.reload',
- }),
- )
+ flashError({
+ title: 'TODO',
+ message: NO_INTERNET_ERROR,
+ infoText: 'actions.reload',
+ variant: 'destructive',
+ duration: 999999999999,
+ })
}
diff --git a/app/App.jsx b/app/App.jsx
index 4c51e95f7..318770060 100644
--- a/app/App.jsx
+++ b/app/App.jsx
@@ -1,6 +1,6 @@
// Import polyfills
// Import styles
-import './styles/application.sass'
+import '@/styles/main.css'
import { ApolloProvider } from '@apollo/client'
// Import libs
@@ -8,12 +8,13 @@ import React from 'react'
import { I18nextProvider } from 'react-i18next'
import { Configure, Index, InstantSearch } from 'react-instantsearch-dom'
import { Provider as ReduxProvider } from 'react-redux'
-import { polyfill as smoothSrollPolyfill } from 'smoothscroll-polyfill'
+import { polyfill as smoothScrollPolyfill } from 'smoothscroll-polyfill'
import { ThemeProvider } from 'styled-components'
// Import APIs so they can load their configurations
import GraphQLClient from './API/graphql_api'
import UserProvider from './components/LoggedInUser/UserProvider'
+import { ToastProvider } from './components/ui/toast'
import { ENTITY_SPEAKER, ENTITY_STATEMENT, ENTITY_VIDEO } from './constants'
import i18n from './i18n/i18n'
import { ALGOLIA_INDEXES_NAMES, searchClient } from './lib/algolia'
@@ -24,34 +25,36 @@ import store from './state'
import theme from './styles/theme'
// Activate polyfills
-smoothSrollPolyfill()
+smoothScrollPolyfill()
const App = () => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
)
export default App
diff --git a/app/components/App/LanguageSelector.jsx b/app/components/App/LanguageSelector.jsx
index 16c63d493..69ffbcf89 100644
--- a/app/components/App/LanguageSelector.jsx
+++ b/app/components/App/LanguageSelector.jsx
@@ -1,10 +1,17 @@
-import { Box, Flex } from '@rebass/grid'
-import classNames from 'classnames'
import { Map } from 'immutable'
import React from 'react'
import { withNamespaces } from 'react-i18next'
import { Globe } from 'styled-icons/fa-solid'
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from '@/components/ui/select'
+import { cn } from '@/lib/css-utils'
+
const defaultLocales = new Map({
en: 'English',
fr: 'Français',
@@ -21,26 +28,25 @@ export default class LanguageSelector extends React.PureComponent {
const options = defaultLocales.merge(this.props.additionalOptions || {}).sortBy((v, k) => k)
return (
-
+
)
}
renderLocalesMap(localesMap) {
return localesMap.entrySeq().map(([key, value]) => (
-
+
))
}
renderIcon() {
- const { value, size } = this.props
+ const { value } = this.props
if (value === 'fr') {
return '🇫🇷'
} else if (value === 'en') {
@@ -56,16 +62,15 @@ export default class LanguageSelector extends React.PureComponent {
} else if (value === 'ru') {
return '🇷🇺'
}
- return
+ return
}
render() {
- const sizeClass = this.props.size ? `is-${this.props.size}` : null
return (
-
- {this.props.withIcon && {this.renderIcon()}}
- {this.renderSelect()}
-
+
+ {this.props.withIcon &&
{this.renderIcon()}
}
+ {this.renderSelect()}
+
)
}
}
diff --git a/app/components/App/Layout.jsx b/app/components/App/Layout.jsx
index f631c3965..391836c6d 100644
--- a/app/components/App/Layout.jsx
+++ b/app/components/App/Layout.jsx
@@ -2,9 +2,11 @@ import React from 'react'
import { Helmet } from 'react-helmet'
import { connect } from 'react-redux'
+import { cn } from '@/lib/css-utils'
+
import { MainModalContainer } from '../Modal/MainModalContainer'
+import { Toaster } from '../ui/toaster'
import PublicAchievementUnlocker from '../Users/PublicAchievementUnlocker'
-import { FlashMessages } from '../Utils'
import BackgroundNotifier from './BackgroundNotifier'
import CrashReportPage from './CrashReportPage'
import Navbar from './Navbar'
@@ -48,24 +50,27 @@ export default class Layout extends React.PureComponent {
render() {
const { locale, sidebarExpended, children } = this.props
- const mainContainerClass = sidebarExpended ? undefined : 'expended'
return (
-
- {this.renderMetadata()}
-
-
-
-
-
- {!this.state.error ? children :
}
+
+
+ {this.renderMetadata()}
+
+
+
+
+ {!this.state.error ? children : }
+
+
+
-
-
-
+
+
)
}
diff --git a/app/components/App/Logo.jsx b/app/components/App/Logo.jsx
index e891055fb..41d1ae255 100644
--- a/app/components/App/Logo.jsx
+++ b/app/components/App/Logo.jsx
@@ -29,10 +29,12 @@ const Image = styled.img`
* The main website logo.
*/
const Logo = ({ borderless, height }) => (
-
+
- aptain
-
+
+ aptain
+
+
Fact
diff --git a/app/components/App/Navbar.jsx b/app/components/App/Navbar.jsx
index 3063d91ab..d425c79ca 100644
--- a/app/components/App/Navbar.jsx
+++ b/app/components/App/Navbar.jsx
@@ -1,12 +1,12 @@
import { Box, Flex } from '@rebass/grid'
import { omit } from 'lodash'
+import { LogIn } from 'lucide-react'
import React from 'react'
import { withNamespaces } from 'react-i18next'
import { withResizeDetector } from 'react-resize-detector'
import { Link, withRouter } from 'react-router-dom'
import Popup from 'reactjs-popup'
import styled, { css, withTheme } from 'styled-components'
-import { HelpCircle } from 'styled-icons/boxicons-regular'
import { UserCircle } from 'styled-icons/fa-regular'
import { CaretDown } from 'styled-icons/fa-solid'
import { themeGet } from 'styled-system'
@@ -22,6 +22,7 @@ import Container from '../StyledUtils/Container'
import { fadeIn } from '../StyledUtils/Keyframes'
import StyledLink from '../StyledUtils/StyledLink'
import { Span } from '../StyledUtils/Text'
+import { Button } from '../ui/button'
import ScoreTag from '../Users/ScoreTag'
import UserAppellation from '../Users/UserAppellation'
import UserMenu from '../Users/UserMenu'
@@ -65,7 +66,7 @@ const UserMenuEntry = styled((props) =>
{isAuthenticated ? (
-
-
-
-
+
-
+
{title}
-
+
)}
@@ -260,29 +254,17 @@ const Navbar = ({
) : (
-
-
- {t('menu.login')}
-
-
- {t('menu.extension')}
-
-
- {t('menu.signup')}
+
+
+
+
+
+
-
+
)}
)}
diff --git a/app/components/App/Sidebar.jsx b/app/components/App/Sidebar.jsx
index 87aaf6d54..9e0c0a71c 100644
--- a/app/components/App/Sidebar.jsx
+++ b/app/components/App/Sidebar.jsx
@@ -1,7 +1,7 @@
import { Query } from '@apollo/client/react/components'
-import { Flex } from '@rebass/grid'
import classNames from 'classnames'
import { capitalize, get } from 'lodash'
+import { CircleHelp, Flag, Heart, ListVideo, Puzzle, Users } from 'lucide-react'
import React from 'react'
import { withNamespaces } from 'react-i18next'
import { connect } from 'react-redux'
@@ -27,7 +27,6 @@ import UserLanguageSelector from '../LoggedInUser/UserLanguageSelector'
import { withLoggedInUser } from '../LoggedInUser/UserProvider'
import ExternalLinkNewTab from '../Utils/ExternalLinkNewTab'
import ProgressBar from '../Utils/ProgressBar'
-import RawIcon from '../Utils/RawIcon'
import ReputationGuard from '../Utils/ReputationGuard'
import Tag from '../Utils/Tag'
@@ -42,6 +41,7 @@ const WhiteStar = styled(Star)`
const DailyGainText = styled.p`
color: #858585;
`
+
@connect((state) => ({ sidebarExpended: state.UserPreferences.sidebarExpended }), {
toggleSidebar,
closeSidebar,
@@ -62,15 +62,19 @@ export default class Sidebar extends React.PureComponent {
}
}
- MenuLink({ title, iconName, customLink, className, children, ...props }) {
- const classes = classNames(className, { 'link-with-icon': !!iconName })
+ MenuLink({ title, className, children, ...props }) {
+ const classes = classNames(
+ 'flex items-center px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-md hover:text-gray-900',
+ { 'bg-gray-100': props.isActive },
+ className,
+ )
return (
- {iconName && }
- {customLink ? children : {children}}
+ {children}
)
}
@@ -92,82 +95,99 @@ export default class Sidebar extends React.PureComponent {
render() {
const { sidebarExpended, className, t, isAuthenticated } = this.props
return (
-