eslint & prettier setup
This commit is contained in:
parent
7c42805787
commit
5e2ab86e22
10 changed files with 144 additions and 69 deletions
24
.eslintrc.js
24
.eslintrc.js
|
@ -1,16 +1,16 @@
|
|||
module.exports = {
|
||||
extends: ['standard-with-typescript', 'standard-jsx'],
|
||||
extends: ["standard-with-typescript", "standard-jsx", "prettier"],
|
||||
parserOptions: {
|
||||
project: './tsconfig.json'
|
||||
project: "./tsconfig.json",
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/semi': ['error', 'always'],
|
||||
'@typescript-eslint/no-extra-semi': 'error',
|
||||
'@typescript-eslint/explicit-function-return-type': 0,
|
||||
'@typescript-eslint/strict-boolean-expressions': 0,
|
||||
'@typescript-eslint/no-floating-promises': 0,
|
||||
'@typescript-eslint/prefer-nullish-coalescing': 0,
|
||||
'no-useless-return': 0,
|
||||
'@typescript-eslint/restrict-template-expressions': 0
|
||||
}
|
||||
}
|
||||
"@typescript-eslint/semi": ["error", "always"],
|
||||
"@typescript-eslint/no-extra-semi": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": 0,
|
||||
"@typescript-eslint/strict-boolean-expressions": 0,
|
||||
"@typescript-eslint/no-floating-promises": 0,
|
||||
"@typescript-eslint/prefer-nullish-coalescing": 0,
|
||||
"no-useless-return": 0,
|
||||
"@typescript-eslint/restrict-template-expressions": 0,
|
||||
},
|
||||
};
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@ tmp/
|
|||
node_modules/
|
||||
*.log
|
||||
.env
|
||||
.idea
|
||||
|
|
8
.prettierignore
Normal file
8
.prettierignore
Normal file
|
@ -0,0 +1,8 @@
|
|||
node_modules
|
||||
# Ignore artifacts:
|
||||
build
|
||||
tmp
|
||||
.idea
|
||||
coverage
|
||||
src/ar
|
||||
src/en
|
8
.prettierrc
Normal file
8
.prettierrc
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 2,
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"printWidth": 80,
|
||||
"arrowParens": "avoid"
|
||||
}
|
|
@ -131,6 +131,7 @@ GEM
|
|||
zeitwerk (2.6.1)
|
||||
|
||||
PLATFORMS
|
||||
arm64-darwin-22
|
||||
x86_64-freebsd-13
|
||||
|
||||
DEPENDENCIES
|
||||
|
|
44
package-lock.json
generated
44
package-lock.json
generated
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "al-quran.0x1eef.test",
|
||||
"name": "al-quran",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
@ -10,6 +10,8 @@
|
|||
"classnames": "^2.3.2",
|
||||
"es-cookie": "^1.4.0",
|
||||
"eslint": "^8.26.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"prettier": "^2.7.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"ts-loader": "^9.3.1",
|
||||
|
@ -1318,6 +1320,18 @@
|
|||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-config-prettier": {
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
|
||||
"integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"eslint-config-prettier": "bin/cli.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-config-standard": {
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz",
|
||||
|
@ -3265,6 +3279,21 @@
|
|||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
|
@ -5350,6 +5379,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"eslint-config-prettier": {
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
|
||||
"integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"eslint-config-standard": {
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz",
|
||||
|
@ -6654,6 +6690,12 @@
|
|||
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
|
||||
"dev": true
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"dev": true
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
"classnames": "^2.3.2",
|
||||
"es-cookie": "^1.4.0",
|
||||
"eslint": "^8.26.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"prettier": "^2.7.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"ts-loader": "^9.3.1",
|
||||
|
|
|
@ -1,30 +1,35 @@
|
|||
import { Surah, Ayat, Ayah } from 'lib/Quran';
|
||||
import React, { useEffect } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Surah, Ayat, Ayah } from "lib/Quran";
|
||||
import React, { useEffect } from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
interface StreamProps {
|
||||
surah: Surah
|
||||
stream: Ayat
|
||||
surah: Surah;
|
||||
stream: Ayat;
|
||||
}
|
||||
|
||||
export function Stream ({ surah, stream }: StreamProps) {
|
||||
export function Stream({ surah, stream }: StreamProps) {
|
||||
const endOfStream = stream.length === surah.ayat.length;
|
||||
const ayat = stream.map((ayah: Ayah) => {
|
||||
return (
|
||||
<li key={ayah.id} className='ayah fade'>
|
||||
<span>Surah {surah.id}, Ayah {ayah.id}</span>
|
||||
<li key={ayah.id} className="ayah fade">
|
||||
<span>
|
||||
Surah {surah.id}, Ayah {ayah.id}
|
||||
</span>
|
||||
<p>{ayah.text}</p>
|
||||
</li>
|
||||
);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const el: HTMLElement = document.querySelector('ul.stream');
|
||||
el.scroll({ top: el.offsetHeight * stream.length, behavior: 'smooth' });
|
||||
const el: HTMLElement = document.querySelector("ul.stream");
|
||||
el.scroll({
|
||||
top: el.offsetHeight * stream.length,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}, [stream]);
|
||||
|
||||
return (
|
||||
<ul className={classNames('stream', { 'scroll-y': endOfStream })}>
|
||||
<ul className={classNames("stream", { "scroll-y": endOfStream })}>
|
||||
{ayat}
|
||||
</ul>
|
||||
);
|
||||
|
|
|
@ -1,58 +1,64 @@
|
|||
interface SurahDetails {
|
||||
id: string
|
||||
place_of_revelation: string
|
||||
transliterated_name: string
|
||||
translated_name: string
|
||||
verse_count: number
|
||||
slug: string
|
||||
codepoints: number[]
|
||||
id: string;
|
||||
place_of_revelation: string;
|
||||
transliterated_name: string;
|
||||
translated_name: string;
|
||||
verse_count: number;
|
||||
slug: string;
|
||||
codepoints: number[];
|
||||
}
|
||||
export interface Ayah {id: number, text: string, readTimeMs: number}
|
||||
|
||||
export interface Ayah {
|
||||
id: number;
|
||||
text: string;
|
||||
readTimeMs: number;
|
||||
}
|
||||
|
||||
export type Ayat = Ayah[];
|
||||
|
||||
export class Surah {
|
||||
#details: SurahDetails;
|
||||
ayat: Ayat;
|
||||
|
||||
static fromJSON (details: SurahDetails, ayat: Array<[number, string]>): Surah {
|
||||
static fromJSON(details: SurahDetails, ayat: Array<[number, string]>): Surah {
|
||||
return new Surah(
|
||||
details,
|
||||
ayat.map(([id, text]) => {
|
||||
return {
|
||||
id,
|
||||
text,
|
||||
readTimeMs: text.split(' ').length * 500
|
||||
readTimeMs: text.split(" ").length * 500,
|
||||
};
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
constructor (details: SurahDetails, ayat: Ayat) {
|
||||
constructor(details: SurahDetails, ayat: Ayat) {
|
||||
this.#details = details;
|
||||
this.ayat = ayat;
|
||||
}
|
||||
|
||||
get id () {
|
||||
get id() {
|
||||
return this.#details.id;
|
||||
}
|
||||
|
||||
get name () {
|
||||
get name() {
|
||||
return String.fromCodePoint(...this.#details.codepoints);
|
||||
}
|
||||
|
||||
get transliteratedName () {
|
||||
get transliteratedName() {
|
||||
return this.#details.transliterated_name;
|
||||
}
|
||||
|
||||
get translatedName () {
|
||||
get translatedName() {
|
||||
return this.#details.translated_name;
|
||||
}
|
||||
|
||||
get placeOfRevelation () {
|
||||
get placeOfRevelation() {
|
||||
return this.#details.place_of_revelation;
|
||||
}
|
||||
|
||||
get numberOfAyah () {
|
||||
get numberOfAyah() {
|
||||
return this.#details.verse_count;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,61 +1,63 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import useSurah from 'hooks/useSurah';
|
||||
import { Timer } from 'components/TheQuran/Timer';
|
||||
import { Stream } from 'components/TheQuran/Stream';
|
||||
import { AboutSurah } from 'components/TheQuran/AboutSurah';
|
||||
import { ThemeSelect } from 'components/TheQuran/ThemeSelect';
|
||||
import classNames from 'classnames';
|
||||
import { get as getCookie } from 'es-cookie';
|
||||
import React, { useState, useEffect } from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import useSurah from "hooks/useSurah";
|
||||
import { Timer } from "components/TheQuran/Timer";
|
||||
import { Stream } from "components/TheQuran/Stream";
|
||||
import { AboutSurah } from "components/TheQuran/AboutSurah";
|
||||
import { ThemeSelect } from "components/TheQuran/ThemeSelect";
|
||||
import classNames from "classnames";
|
||||
import { get as getCookie } from "es-cookie";
|
||||
|
||||
interface PageProps {
|
||||
locale: string
|
||||
surahId: number
|
||||
locale: string;
|
||||
surahId: number;
|
||||
}
|
||||
|
||||
function TheSurahPage ({ locale, surahId }: PageProps) {
|
||||
function TheSurahPage({ locale, surahId }: PageProps) {
|
||||
const { surahIsLoaded, surah } = useSurah(locale, surahId);
|
||||
const [stream, setStream] = useState([]);
|
||||
const [theme, setTheme] = useState(getCookie('theme') || 'moon');
|
||||
const [theme, setTheme] = useState(getCookie("theme") || "moon");
|
||||
const streamIsLoaded = !(stream.length === 0);
|
||||
|
||||
useEffect(() => {
|
||||
if (surahIsLoaded) {
|
||||
document.title = [
|
||||
'Al-Quran:',
|
||||
"Al-Quran:",
|
||||
surah.transliteratedName,
|
||||
`(${surah.translatedName})`
|
||||
].join(' ');
|
||||
`(${surah.translatedName})`,
|
||||
].join(" ");
|
||||
setStream([surah.ayat[stream.length]]);
|
||||
}
|
||||
}, [surahIsLoaded]);
|
||||
|
||||
return (
|
||||
<div className={classNames(theme, locale, 'theme')}>
|
||||
<div className='flex-image'>
|
||||
<div className='image' />
|
||||
<div className={classNames(theme, "theme")}>
|
||||
<div className="flex-image">
|
||||
<div className="image" />
|
||||
</div>
|
||||
{streamIsLoaded &&
|
||||
<div className='flex-row'>
|
||||
{streamIsLoaded && (
|
||||
<div className="flex-row">
|
||||
<span />
|
||||
<ThemeSelect theme={theme} setTheme={setTheme} />
|
||||
<span />
|
||||
</div>}
|
||||
</div>
|
||||
)}
|
||||
{streamIsLoaded && <AboutSurah surah={surah} />}
|
||||
{streamIsLoaded && <Stream surah={surah} stream={stream} />}
|
||||
{streamIsLoaded && stream.length < surah.numberOfAyah &&
|
||||
{streamIsLoaded && stream.length < surah.numberOfAyah && (
|
||||
<Timer
|
||||
surah={surah}
|
||||
ayah={surah.ayat[stream.length - 1]}
|
||||
setStream={setStream}
|
||||
stream={stream}
|
||||
/>}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const el = document.querySelector('.surah');
|
||||
const locale = el.getAttribute('data-locale');
|
||||
const surahId = parseInt(el.getAttribute('data-surah-id'));
|
||||
const el = document.querySelector(".surah");
|
||||
const locale = el.getAttribute("data-locale");
|
||||
const surahId = parseInt(el.getAttribute("data-surah-id"));
|
||||
const root = ReactDOM.createRoot(el);
|
||||
root.render(<TheSurahPage locale={locale} surahId={surahId} />);
|
||||
|
|
Loading…
Reference in a new issue