chore: run lint and prettier

This commit is contained in:
Ashhhleyyy 2022-07-27 22:10:23 +01:00
parent 9e0ad448c2
commit d85c59b21e
Signed by: ash
GPG key ID: 83B789081A0878FB
11 changed files with 221 additions and 143 deletions

View file

@ -14,7 +14,9 @@ const COLOUR_MAP: { [P in Style]: string } = {
};
export default function Banner(props: Props) {
return <div className={'border-2 rounded-lg p-3 ' + (COLOUR_MAP[props.style])}>
{props.children}
</div>
return (
<div className={'border-2 rounded-lg p-3 ' + COLOUR_MAP[props.style]}>
{props.children}
</div>
);
}

View file

@ -2,9 +2,8 @@ import {
AnchorHTMLAttributes,
ButtonHTMLAttributes,
DetailedHTMLProps,
RefAttributes,
} from 'react';
import Link, { LinkProps } from 'next/link';
import Link from 'next/link';
interface CustomProps {
noDefaultColous?: boolean;
@ -44,7 +43,10 @@ type LinkButtonProps = AnchorHTMLAttributes<HTMLAnchorElement>;
export function LinkButton({ className, children, ...props }: LinkButtonProps) {
return (
<Link href={props.href || ''}>
<a className={'text-blue-200 hover:underline ' + (className || '')} {...props}>
<a
className={'text-blue-200 hover:underline ' + (className || '')}
{...props}
>
{children}
</a>
</Link>

View file

@ -6,7 +6,23 @@ interface Props {
export default function CompletionBar(props: Props) {
const progress = (props.completed / props.total) * 100;
return <span className={`w-full h-2 bg-red-400 ${props.inline ? 'inline-block' : 'block'} relative overflow-hidden rounded-full`} role="progressbar" aria-valuenow={props.completed} aria-valuemin={0} aria-valuemax={props.total}>
<span className='w-full h-2 absolute top-0 left-0 block bg-green-400' style={{ transform: `translateX(-${100 - progress}%)`, transformOrigin: 'left center' }} />
</span>
return (
<span
className={`w-full h-2 bg-red-400 ${
props.inline ? 'inline-block' : 'block'
} relative overflow-hidden rounded-full`}
role='progressbar'
aria-valuenow={props.completed}
aria-valuemin={0}
aria-valuemax={props.total}
>
<span
className='w-full h-2 absolute top-0 left-0 block bg-green-400'
style={{
transform: `translateX(-${100 - progress}%)`,
transformOrigin: 'left center',
}}
/>
</span>
);
}

View file

@ -1,19 +1,23 @@
import { LinkButton } from "./Button";
import { LinkButton } from './Button';
export default function Footer() {
return <footer className='w-full h-12 bg-gray-900 p-4 gap-1 shadow'>
<ul className='flex flex-row items-center dots-between'>
<li>
Created by <LinkButton href='https://ashhhleyyy.dev'>Ashhhleyyy</LinkButton>.
</li>
return (
<footer className='w-full h-12 bg-gray-900 p-4 gap-1 shadow'>
<ul className='flex flex-row items-center dots-between'>
<li>
Created by{' '}
<LinkButton href='https://ashhhleyyy.dev'>
Ashhhleyyy
</LinkButton>
.
</li>
<li>
Comics are Copyright (c) their original authors
</li>
<li>Comics are Copyright (c) their original authors</li>
<li>
<LinkButton href='/about'>About</LinkButton>
</li>
</ul>
</footer>
<li>
<LinkButton href='/about'>About</LinkButton>
</li>
</ul>
</footer>
);
}

View file

@ -19,7 +19,9 @@ export default function NavBar() {
{status === 'loading' && <>...</>}
{status === 'unauthenticated' && (
<LinkButton
href={`/login?return=${encodeURIComponent(router.asPath)}`}
href={`/login?return=${encodeURIComponent(
router.asPath
)}`}
>
Log in
</LinkButton>
@ -32,7 +34,6 @@ export default function NavBar() {
)}
</li>
</ul>
</nav>
);
}

View file

@ -1,43 +1,53 @@
import Head from "next/head";
import Banner from "../components/Banner";
import { LinkButton } from "../components/Button";
import Head from 'next/head';
import Banner from '../components/Banner';
import { LinkButton } from '../components/Button';
export default function About() {
return <main className='p-4 max-w-2xl'>
<Head>
<title>About Comicbox</title>
</Head>
return (
<main className='p-4 max-w-2xl'>
<Head>
<title>About Comicbox</title>
</Head>
<section>
<h1 className='text-4xl'>About Comicbox</h1>
<section>
<h1 className='text-4xl'>About Comicbox</h1>
<p>
Comicbox is an <LinkButton href='https://git.ashhhleyyy.dev/ash/comicbox'>open-source</LinkButton> website for
crowdsourcing transcriptions for webcomics. Anyone can <LinkButton href='/login'>log in</LinkButton> and help
transcribing pages.
</p>
</section>
<p>
Comicbox is an{' '}
<LinkButton href='https://git.ashhhleyyy.dev/ash/comicbox'>
open-source
</LinkButton>{' '}
website for crowdsourcing transcriptions for webcomics.
Anyone can <LinkButton href='/login'>log in</LinkButton> and
help transcribing pages.
</p>
</section>
<section>
<h2 className='text-3xl'>How to help?</h2>
<section>
<h2 className='text-3xl'>How to help?</h2>
<p>
You can <LinkButton href='/login'>log in</LinkButton> with Discord or GitHub right away to start, just pick
a comic on the <LinkButton href='/'>homepage</LinkButton> and use the 'Random Page' links from there.
<p>
You can <LinkButton href='/login'>log in</LinkButton> with
Discord or GitHub right away to start, just pick a comic on
the <LinkButton href='/'>homepage</LinkButton> and use the
&apos;Random Page&apos; links from there.
<br />
On the transcription page, you can draw boxes around each
bubble on the page, and once you have checked the order,
click &apos;Extract text&apos; to attempt to automatically
extract the text from each bubble. This may take a few
seconds to complete, and once it has, then all the boxes
will be filled with the text. You can then select these to
edit the text and assign the correct character. Once you are
done with a page, you can click save to submit your changes.
</p>
<br />
On the transcription page, you can draw boxes around each bubble on the page, and once you have checked
the order, click 'Extract text' to attempt to automatically extract the text from each bubble. This may
take a few seconds to complete, and once it has, then all the boxes will be filled with the text. You can
then select these to edit the text and assign the correct character. Once you are done with a page, you can
click save to submit your changes.
</p>
<Banner style="warning">
I would recommend that you have fully read any comics you choose before starting, as otherwise you may
see pages you haven't read yet.
</Banner>
</section>
</main>
<Banner style='warning'>
I would recommend that you have fully read any comics you
choose before starting, as otherwise you may see pages you
haven&apos;t read yet.
</Banner>
</section>
</main>
);
}

View file

@ -37,40 +37,55 @@ export default function ComicPage({ comic, completion }: Props) {
{completion.totalPages} pages have been transcribed!
</p>
<div className='max-w-md'>
<CompletionBar total={completion.totalPages} completed={completion.completePages} />
<CompletionBar
total={completion.totalPages}
completed={completion.completePages}
/>
</div>
</section>
<nav>
{status === 'authenticated' && <ul>
<li>
<LinkButton
href={`/comic/${comic.slug}/transcribe/random`}
>
Random page
</LinkButton>
</li>
<li>
<LinkButton
href={`/comic/${comic.slug}/transcribe/random?completed=true`}
>
Random page (complete)
</LinkButton>
</li>
<li>
<LinkButton
href={`/comic/${comic.slug}/transcribe/random?completed=false`}
>
Random page (incomplete)
</LinkButton>
</li>
</ul>}
{status === 'authenticated' && (
<ul>
<li>
<LinkButton
href={`/comic/${comic.slug}/transcribe/random`}
>
Random page
</LinkButton>
</li>
<li>
<LinkButton
href={`/comic/${comic.slug}/transcribe/random?completed=true`}
>
Random page (complete)
</LinkButton>
</li>
<li>
<LinkButton
href={`/comic/${comic.slug}/transcribe/random?completed=false`}
>
Random page (incomplete)
</LinkButton>
</li>
</ul>
)}
{status === 'loading' && <>Loading...</>}
{status === 'unauthenticated' && <>
Please <LinkButton href={`/login?return=${encodeURIComponent(router.asPath)}`}>Log in</LinkButton> to contribute.
</>}
{status === 'unauthenticated' && (
<>
Please{' '}
<LinkButton
href={`/login?return=${encodeURIComponent(
router.asPath
)}`}
>
Log in
</LinkButton>{' '}
to contribute.
</>
)}
</nav>
</main>
);

View file

@ -173,18 +173,25 @@ export default function TranscribePage(props: Props) {
{props.page.id > 1 && (
<LinkButton
className='flex-1 w-full text-center'
href={`/comic/${props.page.comic.slug}/transcribe/${props.page.id - 1}`}>
href={`/comic/${
props.page.comic.slug
}/transcribe/${props.page.id - 1}`}
>
&larr; Previous page
</LinkButton>
)}
<LinkButton
className='flex-1 w-full text-center'
href={`/comic/${props.page.comic.slug}/transcribe/random`}>
href={`/comic/${props.page.comic.slug}/transcribe/random`}
>
Random page
</LinkButton>
<LinkButton
className='flex-1 w-full text-center'
href={`/comic/${props.page.comic.slug}/transcribe/${props.page.id + 1}`}>
href={`/comic/${
props.page.comic.slug
}/transcribe/${props.page.id + 1}`}
>
Next page &rarr;
</LinkButton>
</nav>

View file

@ -1,5 +1,5 @@
import { Comic } from '@prisma/client';
import type { GetServerSideProps, NextPage } from 'next';
import type { GetServerSideProps } from 'next';
import Head from 'next/head';
import { LinkButton } from '../components/Button';
import CompletionBar from '../components/CompletionBar';
@ -15,7 +15,7 @@ interface Props {
}[];
}
const Home: NextPage<Props> = (props) => {
const Home = (props: Props) => {
return (
<main className='p-4'>
<Head>
@ -32,24 +32,34 @@ const Home: NextPage<Props> = (props) => {
</thead>
<tbody>
{props.comics.map(({ comic, completion }) => {
return <tr key={comic.id}>
<td>
<LinkButton href={`/comic/${comic.slug}`}>
{comic.title}
</LinkButton>
</td>
<td className='w-96 flex flex-row items-center'>
<CompletionBar inline total={completion.totalPages} completed={completion.completePages} />
<span className='whitespace-nowrap pl-2'>
({completion.completePages}/{completion.totalPages} pages)
</span>
</td>
<td>
<LinkButton href={comic.url} target='_blank'>
{new URL(comic.url).host}
</LinkButton>
</td>
</tr>
return (
<tr key={comic.id}>
<td>
<LinkButton href={`/comic/${comic.slug}`}>
{comic.title}
</LinkButton>
</td>
<td className='w-96 flex flex-row items-center'>
<CompletionBar
inline
total={completion.totalPages}
completed={completion.completePages}
/>
<span className='whitespace-nowrap pl-2'>
({completion.completePages}/
{completion.totalPages} pages)
</span>
</td>
<td>
<LinkButton
href={comic.url}
target='_blank'
>
{new URL(comic.url).host}
</LinkButton>
</td>
</tr>
);
})}
</tbody>
</table>
@ -61,33 +71,36 @@ export default Home;
export const getServerSideProps: GetServerSideProps<Props> = async () => {
const comics = await prisma.comic.findMany();
const comicsWithCompletions = await Promise.all(comics.map(async (comic) => {
const pages = await prisma.comicPage.findMany({
where: {
comicId: comic.id,
},
select: {
_count: {
select: {
bubbles: true,
const comicsWithCompletions = await Promise.all(
comics.map(async (comic) => {
const pages = await prisma.comicPage.findMany({
where: {
comicId: comic.id,
},
select: {
_count: {
select: {
bubbles: true,
},
},
},
},
});
});
return {
comic,
completion: {
totalPages: pages.length,
completePages: pages.filter((page) => page._count.bubbles !== 0)
.length,
},
}
}));
return {
comic,
completion: {
totalPages: pages.length,
completePages: pages.filter(
(page) => page._count.bubbles !== 0
).length,
},
};
})
);
return {
props: {
comics: comicsWithCompletions,
}
}
}
},
};
};

View file

@ -16,8 +16,10 @@ export default function Login() {
? router.query.callbackUrl[0]
: router.query.callbackUrl) ||
'/';
const error = Array.isArray(router.query.error) ? router.query.error[0] : router.query.error;
const error = Array.isArray(router.query.error)
? router.query.error[0]
: router.query.error;
return (
<div className='p-4 flex flex-col items-center justify-center'>
@ -30,14 +32,20 @@ export default function Login() {
<h1 className='text-4xl'>Login</h1>
</header>
{error && <>
<hr className='border-slate-600 my-4' />
{error && (
<>
<hr className='border-slate-600 my-4' />
<Banner style='error'>
{error === 'SessionRequired' && <>You must login to view this page.</>}
{error === 'Default' && <>An error occurred {':('} Please try again.</>}
</Banner>
</>}
<Banner style='error'>
{error === 'SessionRequired' && (
<>You must login to view this page.</>
)}
{error === 'Default' && (
<>An error occurred {':('} Please try again.</>
)}
</Banner>
</>
)}
<hr className='border-slate-600 my-4' />

View file

@ -10,7 +10,7 @@
@layer components {
.dots-between > li:not(:last-child)::after {
content: "⦁";
content: '⦁';
padding: 0 8px;
}
}