Editor Help Modal (#99)

* removed css from body
* added internal-link and translated-internal-link
* icon in links are always fixedWidth
* added help button

Signed-off-by: Philip Molares <philip.molares@udo.edu>
Co-authored-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
This commit is contained in:
Philip Molares 2020-05-31 11:36:27 +02:00 committed by GitHub
parent 5da45c2dfd
commit 177f639492
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 399 additions and 68 deletions

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "جهات الاتصال", "title": "جهات الاتصال",
"community": "انضم إلى المجتمع", "community": "انضم إلى المجتمع",
"meetUsOn": "قابِلنا في %s", "meetUsOn": "قابِلنا في {{service}}",
"helpTranslating": "ساعدنا في الترجمة", "helpTranslating": "ساعدنا في الترجمة",
"reportIssue": "بلغ عن خطأ" "reportIssue": "بلغ عن خطأ"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Contactes", "title": "Contactes",
"community": "Unir-se a la comunitat", "community": "Unir-se a la comunitat",
"meetUsOn": "Coneix-nos a %s", "meetUsOn": "Coneix-nos a {{service}}",
"helpTranslating": "Ajuda'ns traduïnt", "helpTranslating": "Ajuda'ns traduïnt",
"reportIssue": "Reportar un problema" "reportIssue": "Reportar un problema"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Kontakty", "title": "Kontakty",
"community": "Připojit ke komunitě", "community": "Připojit ke komunitě",
"meetUsOn": "Potkejte se s námi na %s", "meetUsOn": "Potkejte se s námi na {{service}}",
"helpTranslating": "Pomoci nám s překladem", "helpTranslating": "Pomoci nám s překladem",
"reportIssue": "Nahlásit problém" "reportIssue": "Nahlásit problém"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Kontakte", "title": "Kontakte",
"community": "Tritt der Community bei", "community": "Tritt der Community bei",
"meetUsOn": "Triff uns auf %s", "meetUsOn": "Triff uns auf {{service}}",
"helpTranslating": "Hilf uns beim Übersetzen", "helpTranslating": "Hilf uns beim Übersetzen",
"reportIssue": "Fehlerbericht senden" "reportIssue": "Fehlerbericht senden"
}, },
@ -193,4 +193,4 @@
} }
} }
} }
} }

View file

@ -82,7 +82,7 @@
"contacts": { "contacts": {
"title": "Contacts", "title": "Contacts",
"community": "Join the community", "community": "Join the community",
"meetUsOn": "Meet us on %s", "meetUsOn": "Meet us on {{service}}",
"helpTranslating": "Help us translating", "helpTranslating": "Help us translating",
"reportIssue": "Report an issue" "reportIssue": "Report an issue"
}, },
@ -224,7 +224,7 @@
"openIdLogin": "Invalid OpenID provided", "openIdLogin": "Invalid OpenID provided",
"emailLogin": "Invalid email or password", "emailLogin": "Invalid email or password",
"ldapLogin": "Invalid username or password" "ldapLogin": "Invalid username or password"
} }
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Contactos", "title": "Contactos",
"community": "Únete a la comunidad", "community": "Únete a la comunidad",
"meetUsOn": "Encuéntranos en %s", "meetUsOn": "Encuéntranos en {{service}}",
"helpTranslating": "Ayúdanos traduciendo", "helpTranslating": "Ayúdanos traduciendo",
"reportIssue": "Reportar un problema" "reportIssue": "Reportar un problema"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Contacts", "title": "Contacts",
"community": "Rejoignez la communauté", "community": "Rejoignez la communauté",
"meetUsOn": "Rencontrez-nous sur %s", "meetUsOn": "Rencontrez-nous sur {{service}}",
"helpTranslating": "Aidez-nous à traduire", "helpTranslating": "Aidez-nous à traduire",
"reportIssue": "Signaler un problème" "reportIssue": "Signaler un problème"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Kontak", "title": "Kontak",
"community": "Bergabung dengan komunitas", "community": "Bergabung dengan komunitas",
"meetUsOn": "Temui kami di %s", "meetUsOn": "Temui kami di {{service}}",
"helpTranslating": "Bantu kami menerjemahkan", "helpTranslating": "Bantu kami menerjemahkan",
"reportIssue": "Laporkan kesalahan" "reportIssue": "Laporkan kesalahan"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Contatti", "title": "Contatti",
"community": "Unisciti alla comunità", "community": "Unisciti alla comunità",
"meetUsOn": "Vieni a trovarci su %s", "meetUsOn": "Vieni a trovarci su {{service}}",
"helpTranslating": "Aiutaci nella traduzione", "helpTranslating": "Aiutaci nella traduzione",
"reportIssue": "Segnala un problema" "reportIssue": "Segnala un problema"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "コンタクト", "title": "コンタクト",
"community": "コミュニティに参加しましょう", "community": "コミュニティに参加しましょう",
"meetUsOn": "%sでチャットする", "meetUsOn": "{{service}}でチャットする",
"helpTranslating": "翻訳のお手伝いをお願いします", "helpTranslating": "翻訳のお手伝いをお願いします",
"reportIssue": "問題を報告する" "reportIssue": "問題を報告する"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -61,7 +61,7 @@
"help": { "help": {
"contacts": { "contacts": {
"title": "연락처", "title": "연락처",
"meetUsOn": "%s에서 만나보세요", "meetUsOn": "{{service}}에서 만나보세요",
"reportIssue": "이슈 보고하기" "reportIssue": "이슈 보고하기"
}, },
"documents": { "documents": {
@ -181,4 +181,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Contacten", "title": "Contacten",
"community": "Lid worden", "community": "Lid worden",
"meetUsOn": "Ontmoet ons op %s", "meetUsOn": "Ontmoet ons op {{service}}",
"helpTranslating": "Help ons vertalen", "helpTranslating": "Help ons vertalen",
"reportIssue": "Probleem rapporteren" "reportIssue": "Probleem rapporteren"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Kontakty", "title": "Kontakty",
"community": "Dołącz do społeczności", "community": "Dołącz do społeczności",
"meetUsOn": "Spotkaj się z nami na %s", "meetUsOn": "Spotkaj się z nami na {{service}}",
"helpTranslating": "Pomóż nam w tłumaczeniu", "helpTranslating": "Pomóż nam w tłumaczeniu",
"reportIssue": "Zgłoś błąd" "reportIssue": "Zgłoś błąd"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Contatos", "title": "Contatos",
"community": "Join the community", "community": "Join the community",
"meetUsOn": "Meet us on %s", "meetUsOn": "Meet us on {{service}}",
"helpTranslating": "Help us translating", "helpTranslating": "Help us translating",
"reportIssue": "Relatar um problema" "reportIssue": "Relatar um problema"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Контакты", "title": "Контакты",
"community": "Присоединиться к сообществу", "community": "Присоединиться к сообществу",
"meetUsOn": "Познакомьтесь с нами в %s", "meetUsOn": "Познакомьтесь с нами в {{service}}",
"helpTranslating": "Помочь с переводом", "helpTranslating": "Помочь с переводом",
"reportIssue": "Сообщить о проблеме" "reportIssue": "Сообщить о проблеме"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Kontakty", "title": "Kontakty",
"community": "Pripojiť sa ku komunite", "community": "Pripojiť sa ku komunite",
"meetUsOn": "Stretnite nás na %s", "meetUsOn": "Stretnite nás na {{service}}",
"helpTranslating": "Pomôžte nám s prekladom", "helpTranslating": "Pomôžte nám s prekladom",
"reportIssue": "Nahlásiť problém" "reportIssue": "Nahlásiť problém"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -63,7 +63,7 @@
"contacts": { "contacts": {
"title": "Контакти", "title": "Контакти",
"community": "Приступите заједници", "community": "Приступите заједници",
"meetUsOn": "Пронађите нас на %s", "meetUsOn": "Пронађите нас на {{service}}",
"helpTranslating": "Помозите око превода", "helpTranslating": "Помозите око превода",
"reportIssue": "Пријава проблема" "reportIssue": "Пријава проблема"
}, },
@ -185,4 +185,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "Kontakter", "title": "Kontakter",
"community": "Gå med i samhället", "community": "Gå med i samhället",
"meetUsOn": "Träffa oss på %s", "meetUsOn": "Träffa oss på {{service}}",
"helpTranslating": "Hjälp oss att översätta", "helpTranslating": "Hjälp oss att översätta",
"reportIssue": "Rapportera ett fel" "reportIssue": "Rapportera ett fel"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -63,7 +63,7 @@
"contacts": { "contacts": {
"title": "Liên Lạc", "title": "Liên Lạc",
"community": "Tham gia vào cộng đồng", "community": "Tham gia vào cộng đồng",
"meetUsOn": "Gặp chúng tôi ở %s", "meetUsOn": "Gặp chúng tôi ở {{service}}",
"helpTranslating": "Giúp chúng tôi dịch", "helpTranslating": "Giúp chúng tôi dịch",
"reportIssue": "Báo cáo vấn đề" "reportIssue": "Báo cáo vấn đề"
}, },
@ -185,4 +185,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "联系我们", "title": "联系我们",
"community": "加入社区", "community": "加入社区",
"meetUsOn": "在 %s 上联系我们", "meetUsOn": "在 {{service}} 上联系我们",
"helpTranslating": "帮助我们翻译", "helpTranslating": "帮助我们翻译",
"reportIssue": "报告问题" "reportIssue": "报告问题"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -64,7 +64,7 @@
"contacts": { "contacts": {
"title": "聯絡方式", "title": "聯絡方式",
"community": "加入社群", "community": "加入社群",
"meetUsOn": "透過 %s 聯絡我們", "meetUsOn": "透過 {{service}} 聯絡我們",
"helpTranslating": "幫助我們改進翻譯", "helpTranslating": "幫助我們改進翻譯",
"reportIssue": "回報問題" "reportIssue": "回報問題"
}, },
@ -186,4 +186,4 @@
"error": {} "error": {}
} }
} }
} }

View file

@ -9,7 +9,7 @@ export interface LoadingScreenProps {
export const LoadingScreen: React.FC<LoadingScreenProps> = ({ failedTitle }) => { export const LoadingScreen: React.FC<LoadingScreenProps> = ({ failedTitle }) => {
return ( return (
<div className="loader middle"> <div className="loader middle">
<div className="icon"> <div className="icon text-white">
<FontAwesomeIcon icon="file-alt" size="6x" <FontAwesomeIcon icon="file-alt" size="6x"
className={failedTitle ? 'animation-shake' : 'animation-pulse'}/> className={failedTitle ? 'animation-shake' : 'animation-pulse'}/>
</div> </div>

View file

@ -0,0 +1,290 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import React, { Fragment, useState } from 'react'
import { Button, Card, Col, Modal, Row, Table } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
import { TranslatedExternalLink } from '../../links/translated-external-link'
export const HelpButton: React.FC = () => {
const { t } = useTranslation()
const [show, setShow] = useState(false)
const handleShow = () => setShow(true)
const handleClose = () => setShow(false)
return (
<Fragment>
<Button title={t('editor.menu.help')} className="ml-2 text-secondary" size="sm" variant="outline-light"
onClick={handleShow}>
<FontAwesomeIcon icon="question-circle"/>
</Button>
<Modal show={show} onHide={handleClose} animation={true} className="text-dark" size='lg'>
<Modal.Header closeButton>
<Modal.Title>
<FontAwesomeIcon icon="question-circle"/> <Trans i18nKey={'editor.menu.help'}/>
</Modal.Title>
</Modal.Header>
<Modal.Body className="text-dark">
<Row>
<Col lg={4}>
<Card>
<Card.Header><Trans i18nKey='editor.help.contacts.title'/></Card.Header>
<Card.Body>
<Card.Text>
<ul className="list-unstyled">
<li>
<TranslatedExternalLink
i18nKey='editor.help.contacts.community'
href='https://community.codimd.org/'
icon='users'
className='text-primary'
/>
</li>
<li>
<TranslatedExternalLink
i18nKey='editor.help.contacts.meetUsOn'
i18nOption={{ service: 'Matrix' }}
href='https://riot.im/app/#/room/#codimd:matrix.org'
icon='hashtag'
className='text-primary'
/>
</li>
<li>
<TranslatedExternalLink
i18nKey='editor.help.contacts.reportIssue'
href='https://github.com/codimd/server/issues'
icon='tag'
className='text-primary'
/>
</li>
<li>
<TranslatedExternalLink
i18nKey='editor.help.contacts.helpTranslating'
href='https://translate.codimd.org/'
icon='language'
className='text-primary'
/>
</li>
</ul>
</Card.Text>
</Card.Body>
</Card>
<Card>
<Card.Header><Trans i18nKey='editor.help.documents.title'/></Card.Header>
<Card.Body>
<Card.Text>
<ul className="list-unstyled">
<li>
<TranslatedExternalLink
i18nKey='editor.help.documents.features'
href='/n/features'
icon='dot-circle'
className='text-primary'
/>
</li>
<li>
<TranslatedExternalLink
i18nKey='editor.help.documents.yamlMetadata'
href='/n/yaml-data'
icon='dot-circle'
className='text-primary'
/>
</li>
<li>
<TranslatedExternalLink
i18nKey='editor.help.documents.slideExample'
href='https://github.com/codimd/server/issues'
icon='dot-circle'
className='text-primary'
/>
</li>
</ul>
</Card.Text>
</Card.Body>
</Card>
</Col>
<Col lg={8}>
<Card>
<Card.Header><Trans i18nKey='editor.help.cheatsheet.title'/></Card.Header>
<Card.Body>
<Card.Text>
<Table className="table-condensed table-cheatsheet">
<thead>
<tr>
<td><Trans i18nKey='editor.help.cheatsheet.example'/></td>
<td><Trans i18nKey='editor.help.cheatsheet.syntax'/></td>
</tr>
</thead>
<tbody className="markdown-body"
style={{ fontFamily: 'inherit', fontSize: '14px', padding: 0, maxWidth: 'inherit' }}>
<tr>
<td><Trans i18nKey='editor.editorToolbar.header'/></td>
<td>
<pre># <Trans i18nKey='editor.editorToolbar.header'/></pre>
</td>
</tr>
<tr>
<td>
<ul>
<li><Trans i18nKey='editor.editorToolbar.unorderedList'/></li>
</ul>
</td>
<td>
<pre>- <Trans i18nKey='editor.editorToolbar.unorderedList'/></pre>
</td>
</tr>
<tr>
<td>
<ol>
<li><Trans i18nKey='editor.editorToolbar.orderedList'/></li>
</ol>
</td>
<td>
<pre>1. <Trans i18nKey='editor.editorToolbar.orderedList'/></pre>
</td>
</tr>
<tr>
<td>
<ul>
<li className="task-list-item">
<input type="checkbox" className="task-list-item-checkbox" disabled={false}/>
<label><Trans i18nKey='editor.editorToolbar.checkList'/></label>
</li>
</ul>
</td>
<td>
<pre>- [ ] <Trans i18nKey='editor.editorToolbar.checkList'/></pre>
</td>
</tr>
<tr>
<td>
<blockquote><Trans i18nKey='editor.editorToolbar.blockquote'/></blockquote>
</td>
<td>
<pre>> <Trans i18nKey='editor.editorToolbar.blockquote'/></pre>
</td>
</tr>
<tr>
<td><strong><Trans i18nKey='editor.editorToolbar.bold'/></strong></td>
<td>
<pre>**<Trans i18nKey='editor.editorToolbar.bold'/>**</pre>
</td>
</tr>
<tr>
<td><i><Trans i18nKey='editor.editorToolbar.italic'/></i></td>
<td>
<pre>*<Trans i18nKey='editor.editorToolbar.italic'/>*</pre>
</td>
</tr>
<tr>
<td><s><Trans i18nKey='editor.editorToolbar.strikethrough'/></s></td>
<td>
<pre>~~<Trans i18nKey='editor.editorToolbar.strikethrough'/>~~</pre>
</td>
</tr>
<tr>
<td>19<sup>th</sup></td>
<td>
<pre>19^th^</pre>
</td>
</tr>
<tr>
<td>H<sub>2</sub>O</td>
<td>
<pre>H~2~O</pre>
</td>
</tr>
<tr>
<td>
<ins><Trans i18nKey='editor.help.cheatsheet.underlinedText'/></ins>
</td>
<td>
<pre>++<Trans i18nKey='editor.help.cheatsheet.underlinedText'/>++</pre>
</td>
</tr>
<tr>
<td>
<mark><Trans i18nKey='editor.help.cheatsheet.highlightedText'/></mark>
</td>
<td>
<pre>==<Trans i18nKey='editor.help.cheatsheet.highlightedText'/>==</pre>
</td>
</tr>
<tr>
<td><a href='https://example.com'><Trans i18nKey='editor.editorToolbar.link'/></a></td>
<td>
<pre>[link text](https://example.com)</pre>
</td>
</tr>
<tr>
<td><Trans i18nKey='editor.editorToolbar.image'/></td>
<td>
<pre>![image alt](https:// "title")</pre>
</td>
</tr>
<tr>
<td><code><Trans i18nKey='editor.editorToolbar.code'/></code></td>
<td>
<pre>`<Trans i18nKey='editor.editorToolbar.code'/>`</pre>
</td>
</tr>
<tr>
<td>
<pre style={{ border: 'none !important' }}>
<code className="javascript hljs">
<div className="wrapper">
<div className="gutter linenumber">
<span data-linenumber="1"/>
</div>
<div className="code">
<span className="hljs-keyword">var</span> x = <span className="hljs-number">5</span>;
</div>
</div>
</code>
</pre>
</td>
<td>
<pre>```javascript<br/>var x = 5;<br/>```</pre>
</td>
</tr>
<tr>
<td><img alt=":smile:" className="emoji" src="./build/emojify.js/dist/images/basic/smile.png"
title=":smile:"/></td>
<td>
<pre>:smile:</pre>
</td>
</tr>
<tr>
<td>Extern</td>
<td>
<pre>{'{'}%youtube youtube_id %{'}'}</pre>
</td>
</tr>
<tr>
<td>L<sup>a</sup>T<sub>e</sub>X</td>
<td>
<pre>$L^aT_eX$</pre>
</td>
</tr>
<tr>
<td>
<div className="alert alert-info">
<p>
<Trans i18nKey='editor.help.cheatsheet.exampleAlert'/>
</p>
</div>
</td>
<td>
<pre>:::info<br/><Trans i18nKey='editor.help.cheatsheet.exampleAlert'/><br/>:::</pre>
</td>
</tr>
</tbody>
</Table>
</Card.Text>
</Card.Body>
</Card>
</Col>
</Row>
</Modal.Body>
</Modal>
</Fragment>
)
}

View file

@ -7,6 +7,7 @@ import { EditorViewMode } from './editor-view-mode'
import { Trans, useTranslation } from 'react-i18next' import { Trans, useTranslation } from 'react-i18next'
import { EditorMenu } from './editor-menu' import { EditorMenu } from './editor-menu'
import { ConnectionIndicator } from './connection-indicator' import { ConnectionIndicator } from './connection-indicator'
import { HelpButton } from './help-button'
const TaskBar: React.FC = () => { const TaskBar: React.FC = () => {
useTranslation() useTranslation()
@ -20,10 +21,7 @@ const TaskBar: React.FC = () => {
</Navbar.Brand> </Navbar.Brand>
<EditorViewMode/> <EditorViewMode/>
<DarkModeButton/> <DarkModeButton/>
<Button className="ml-2 text-secondary" size="sm" <HelpButton/>
variant="outline-light">
<FontAwesomeIcon icon="question-circle"/>
</Button>
</Nav> </Nav>
<Nav className="d-flex align-items-center text-secondary"> <Nav className="d-flex align-items-center text-secondary">
<Button className="ml-2 text-secondary" size="sm" variant="outline-light"> <Button className="ml-2 text-secondary" size="sm" variant="outline-light">

View file

@ -6,7 +6,7 @@ import './layout/style/index.scss'
export const LandingLayout: React.FC = ({ children }) => { export const LandingLayout: React.FC = ({ children }) => {
return ( return (
<Container> <Container className="text-center text-white">
<HeaderBar/> <HeaderBar/>
{children} {children}
<Footer/> <Footer/>

View file

@ -4,16 +4,12 @@ import { useSelector } from 'react-redux'
import { ApplicationState } from '../../../../redux' import { ApplicationState } from '../../../../redux'
import { ExternalLink } from '../../../links/external-link' import { ExternalLink } from '../../../links/external-link'
import { TranslatedExternalLink } from '../../../links/translated-external-link' import { TranslatedExternalLink } from '../../../links/translated-external-link'
import { TranslatedInternalLink } from '../../../links/translated-internal-link'
import { VersionInfo } from '../version-info/version-info' import { VersionInfo } from '../version-info/version-info'
export const PoweredByLinks: React.FC = () => { export const PoweredByLinks: React.FC = () => {
useTranslation() useTranslation()
const defaultLinks =
{
releases: '/n/release-notes'
}
const config = useSelector((state: ApplicationState) => state.backendConfig) const config = useSelector((state: ApplicationState) => state.backendConfig)
return ( return (
@ -21,8 +17,10 @@ export const PoweredByLinks: React.FC = () => {
<Trans i18nKey="landing.footer.poweredBy"> <Trans i18nKey="landing.footer.poweredBy">
<ExternalLink href="https://codimd.org" text="CodiMD"/> <ExternalLink href="https://codimd.org" text="CodiMD"/>
</Trans> </Trans>
&nbsp;|&nbsp;
<TranslatedInternalLink path='/n/release-notes' i18nKey='landing.footer.releases'/>
{ {
Object.entries({ ...defaultLinks, ...(config.specialLinks) }).map(([i18nKey, href]) => Object.entries({ ...config.specialLinks }).map(([i18nKey, href]) =>
<Fragment key={i18nKey}> <Fragment key={i18nKey}>
&nbsp;|&nbsp; &nbsp;|&nbsp;
<TranslatedExternalLink href={href} i18nKey={'landing.footer.' + i18nKey}/> <TranslatedExternalLink href={href} i18nKey={'landing.footer.' + i18nKey}/>

View file

@ -7,8 +7,6 @@ html {
} }
body { body {
min-height: 100%; min-height: 100%;
color: #fff;
text-align: center;
//text-shadow: 0 1px 3px rgba(0, 0, 0, .5); //text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
font-family: "Source Sans Pro", Helvetica, Arial, sans-serif; font-family: "Source Sans Pro", Helvetica, Arial, sans-serif;
} }

View file

@ -4,12 +4,15 @@ import { IconProp } from '../../utils/iconProp'
export interface ExternalLinkProp { export interface ExternalLinkProp {
href: string; href: string;
text: string;
icon?: IconProp; icon?: IconProp;
className?: string className?: string
} }
export const ExternalLink: React.FC<ExternalLinkProp> = ({ href, text, icon, className = 'text-light' }) => { export interface ExternalLinkTextProp {
text: string;
}
export const ExternalLink: React.FC<ExternalLinkProp & ExternalLinkTextProp> = ({ href, text, icon, className = 'text-light' }) => {
return ( return (
<a href={href} <a href={href}
target="_blank" target="_blank"
@ -18,7 +21,7 @@ export const ExternalLink: React.FC<ExternalLinkProp> = ({ href, text, icon, cla
{ {
icon icon
? <Fragment> ? <Fragment>
<FontAwesomeIcon icon={icon}/>&nbsp; <FontAwesomeIcon icon={icon} fixedWidth={true}/>&nbsp;
</Fragment> </Fragment>
: null : null
} }

View file

@ -0,0 +1,30 @@
import React, { Fragment } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { LinkContainer } from 'react-router-bootstrap'
import { IconProp } from '../../utils/iconProp'
export interface InternalLinkProp {
path: string;
icon?: IconProp;
className?: string
}
export interface InternalLinkTextProp {
text: string;
}
export const InternalLink: React.FC<InternalLinkProp & InternalLinkTextProp> = ({ path, text, icon, className = 'text-light' }) => {
return (
<LinkContainer to={path}
className={className}>
{
icon
? <Fragment>
<FontAwesomeIcon icon={icon} fixedWidth={true}/>&nbsp;
</Fragment>
: null
}
{text}
</LinkContainer>
)
}

View file

@ -1,19 +1,17 @@
import { StringMap, TOptionsBase } from 'i18next'
import React from 'react' import React from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { IconProp } from '../../utils/iconProp' import { ExternalLink, ExternalLinkProp } from './external-link'
import { ExternalLink } from './external-link'
export interface TranslatedLinkProps { export interface TranslatedLinkProps {
i18nKey: string; i18nKey: string;
href: string; i18nOption?: (TOptionsBase & StringMap) | string
icon?: IconProp;
className?: string
} }
const TranslatedExternalLink: React.FC<TranslatedLinkProps> = ({ i18nKey, ...props }) => { const TranslatedExternalLink: React.FC<TranslatedLinkProps & ExternalLinkProp> = ({ i18nKey, i18nOption, ...props }) => {
const { t } = useTranslation() const { t } = useTranslation()
return ( return (
<ExternalLink text={t(i18nKey)} {...props}/> <ExternalLink text={t(i18nKey, i18nOption)} {...props}/>
) )
} }

View file

@ -0,0 +1,11 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import { InternalLink, InternalLinkProp } from './internal-link'
import { TranslatedLinkProps } from './translated-external-link'
export const TranslatedInternalLink: React.FC<TranslatedLinkProps & InternalLinkProp> = ({ i18nKey, i18nOption, ...props }) => {
const { t } = useTranslation()
return (
<InternalLink text={t(i18nKey, i18nOption)} {...props}/>
)
}

View file

@ -19,12 +19,15 @@ import {
faColumns, faColumns,
faComment, faComment,
faCopy, faCopy,
faDotCircle,
faDownload, faDownload,
faEye, faEye,
faFileAlt, faFileAlt,
faFileCode, faFileCode,
faGlobe, faGlobe,
faHashtag,
faHistory, faHistory,
faLanguage,
faMoon, faMoon,
faPaste, faPaste,
faPencilAlt, faPencilAlt,
@ -36,6 +39,7 @@ import {
faSortDown, faSortDown,
faSortUp, faSortUp,
faSync, faSync,
faTag,
faThumbtack, faThumbtack,
faTimes, faTimes,
faTrash, faTrash,
@ -50,5 +54,6 @@ export const setUpFontAwesome: (() => void) = () => {
faThumbtack, faClock, faTimes, faGithub, faGitlab, faGoogle, faFacebook, faThumbtack, faClock, faTimes, faGithub, faGitlab, faGoogle, faFacebook,
faDropbox, faTwitter, faUsers, faAddressCard, faEye, faPencilAlt, faColumns, faDropbox, faTwitter, faUsers, faAddressCard, faEye, faPencilAlt, faColumns,
faMoon, faQuestionCircle, faShareSquare, faHistory, faFileCode, faPaste, faMoon, faQuestionCircle, faShareSquare, faHistory, faFileCode, faPaste,
faCircle, faSort, faDownload, faUpload, faTrash, faSync, faSortUp, faSortDown, faCopy) faCircle, faSort, faDownload, faUpload, faTrash, faSync, faSortUp, faSortDown, faCopy,
faHashtag, faLanguage, faTag, faDotCircle)
} }