mirror of
https://github.com/hazemKrimi/touch-programming.git
synced 2026-05-01 18:20:26 +00:00
Add fonts, spinner and small screen detection
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -7,6 +7,7 @@ import { KEYS_TO_DISABLE } from 'constants/default';
|
||||
import { renderCharacter } from './utils';
|
||||
|
||||
import './index.css';
|
||||
import Spinner from 'components/Spinner';
|
||||
|
||||
type CodeProps = {
|
||||
code: string;
|
||||
@@ -72,6 +73,12 @@ function Code({ code, loaded }: CodeProps) {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [timer, characters]);
|
||||
|
||||
if (!code) return (
|
||||
<div className='code-container'>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className='code-container'>
|
||||
{code.split('').map((char, index) => renderCharacter(code, characters, loaded, char, index))}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
.spinner-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 5px solid var(--white);
|
||||
border-top: 5px solid var(--crimson);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import './index.css';
|
||||
|
||||
function Spinner() {
|
||||
return (
|
||||
<div className='spinner-container'>
|
||||
<div className='spinner'></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Spinner;
|
||||
@@ -34,7 +34,6 @@ export const KEYS_TO_DISABLE = [
|
||||
'ArrowLeft',
|
||||
'ArrowRight',
|
||||
];
|
||||
|
||||
export const SUPPORTED_LANGUAGES = [
|
||||
'javascript',
|
||||
'typescript',
|
||||
|
||||
+15
-1
@@ -1,10 +1,24 @@
|
||||
@font-face {
|
||||
font-family: '0xProto';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: url(assets/fonts/0xProtoNerdFont-Regular.ttf) format(truetype);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: '0xProto';
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
src: url(assets/fonts/0xProtoNerdFont-Bold.ttf) format(truetype);
|
||||
}
|
||||
|
||||
:root {
|
||||
--black: #131314;
|
||||
--white: #dddddd;
|
||||
--crimson: #bd1839;
|
||||
--background: #1d1b1b;
|
||||
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
font-family: '0xProto', sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
|
||||
@@ -34,6 +34,10 @@ header p {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
header span {
|
||||
color: var(--crimson);
|
||||
}
|
||||
|
||||
header .cta {
|
||||
all: unset;
|
||||
cursor: pointer;
|
||||
@@ -52,7 +56,6 @@ header .cta {
|
||||
}
|
||||
|
||||
.features {
|
||||
margin-top: 2rem;
|
||||
padding: 2.5rem 1.25rem;
|
||||
|
||||
display: grid;
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
import { NavLink } from 'react-router';
|
||||
|
||||
import { isMobileBrowser } from 'utils';
|
||||
|
||||
import './index.css';
|
||||
|
||||
function Home() {
|
||||
const isMobile = isMobileBrowser();
|
||||
|
||||
return (
|
||||
<div className='home-container'>
|
||||
<header>
|
||||
<h1>Touch Programming</h1>
|
||||
<p>Master touch typing with real code snippets from your favorite programming languages, powered by AI.</p>
|
||||
<NavLink to='/languages'>
|
||||
{isMobile ?
|
||||
<span>This app is made to be used in a desktop device.</span> :
|
||||
<button className='cta'>
|
||||
Start Typing
|
||||
</button>
|
||||
}
|
||||
</NavLink>
|
||||
</header>
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@ header h1 {
|
||||
color: var(--crimson);
|
||||
}
|
||||
|
||||
header span {
|
||||
color: var(--crimson);
|
||||
}
|
||||
|
||||
.languages-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
|
||||
@@ -1,10 +1,24 @@
|
||||
import { NavLink } from 'react-router';
|
||||
|
||||
import { isMobileBrowser } from 'utils';
|
||||
|
||||
import { SUPPORTED_LANGUAGES } from 'constants/default';
|
||||
|
||||
import './index.css';
|
||||
|
||||
function Languages() {
|
||||
const isMobile = isMobileBrowser();
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<div className='languages-container'>
|
||||
<header>
|
||||
<span>This app is made to be used in a desktop device.</span>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='languages-container'>
|
||||
<header>
|
||||
|
||||
@@ -24,3 +24,7 @@ header h1 {
|
||||
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
header span {
|
||||
color: var(--crimson);
|
||||
}
|
||||
|
||||
@@ -3,17 +3,22 @@ import { useParams } from 'react-router';
|
||||
|
||||
import TypingContextProvider from 'contexts/typing';
|
||||
|
||||
import { isMobileBrowser } from 'utils';
|
||||
|
||||
import Code from 'components/Code';
|
||||
import Stats from 'components/Stats';
|
||||
|
||||
import './index.css';
|
||||
|
||||
function Typing() {
|
||||
const {lang} = useParams();
|
||||
const isMobile = isMobileBrowser();
|
||||
const { lang } = useParams();
|
||||
const [code, setCode] = useState<string>('');
|
||||
const [loaded, setLoaded] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isMobile) return;
|
||||
|
||||
(async function () {
|
||||
setCode('');
|
||||
|
||||
@@ -39,7 +44,17 @@ function Typing() {
|
||||
setCode((prev) => prev.trim());
|
||||
setLoaded(true);
|
||||
})();
|
||||
}, [lang]);
|
||||
}, [isMobile, lang]);
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<div className='typing-container'>
|
||||
<header>
|
||||
<span>This app is made to be used in a desktop device.</span>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TypingContextProvider>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export function isMobileBrowser(): boolean {
|
||||
const width = window.innerWidth;
|
||||
|
||||
return width <= 768 || (width > 768 && width <= 1024);
|
||||
}
|
||||
Reference in New Issue
Block a user