Skip to content

Commit

Permalink
config: configure lint and pre-commit hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
gimnathperera committed Sep 29, 2023
1 parent 2a1bf31 commit 038c559
Show file tree
Hide file tree
Showing 25 changed files with 2,244 additions and 821 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/node_modules
53 changes: 52 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
{
"extends": "next/core-web-vitals"
"extends": ["next/core-web-vitals", "plugin:@typescript-eslint/recommended", "prettier"],
"rules": {
"react/display-name": "off",
"@next/next/no-img-element": "off",
"react/no-unescaped-entities": "off",
"import/no-anonymous-default-export": "off",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/explicit-function-return-type": "error",
"comma-dangle": ["error", "always-multiline"],

// add new line above return
"newline-before-return": "error",
// add new line below import
"import/newline-after-import": [
"error",
{
"count": 1
}
],
"@typescript-eslint/ban-types": [
"error",
{
"extendDefaults": true,
"types": {
"{}": false
}
}
]
},
"plugins": ["import"],
"settings": {
"import/parsers": {
"@typescript-eslint/parser": [".ts", ".tsx"]
},
"import/resolver": {
"typescript": {
"alwaysTryTypes": true,
"project": ["./tsconfig.json"]
}
}
},
"overrides": [
{
"files": ["src/iconify-bundle/*"],
"rules": {
"@typescript-eslint/no-var-requires": "off"
}
}
]
}
41 changes: 41 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

echo '🔍 Preparing to commit: Running code analysis and build process...'

# Check code formatting using Prettier
pnpm check-format ||
(
echo '🔴 Prettier Check Failed: Your code styling does not meet the standards.
Please run "pnpm format", add the changes, and then reattempt the commit.';
false;
)

# Check code quality using ESLint
pnpm check-lint ||
(
echo '🔴 ESLint Check Failed: Your code contains quality issues that need to be addressed.
Review the listed problems, make the necessary changes, and try committing again.'
false;
)

# Validate TypeScript type correctness
pnpm check-types ||
(
echo '🔴 Type Check Failed: There are issues with the TypeScript type correctness.
Please resolve the indicated problems before proceeding.'
false;
)

# If all checks pass, proceed to build
echo '📦 Building the project...'

pnpm build ||
(
echo '🔴 Build Failed: The project failed to build properly.
Examine the error messages above for insights into the issues.'
false;
)

# If all checks and build pass, proceed to commit
echo '✅ All checks passed. Committing changes...'
17 changes: 17 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module.exports = {
arrowParens: 'avoid',
bracketSpacing: true,
htmlWhitespaceSensitivity: 'css',
insertPragma: false,
bracketSameLine: false,
jsxSingleQuote: true,
printWidth: 100,
proseWrap: 'preserve',
quoteProps: 'as-needed',
requirePragma: false,
semi: true,
singleQuote: true,
tabWidth: 2,
trailingComma: 'all',
useTabs: false,
};
36 changes: 17 additions & 19 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import Header from "@/components/header";
import Footer from "@/components/footer";
import { siteConfig } from "@/config/site";
import "@/styles/globals.css";
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import Header from '@/components/header';
import Footer from '@/components/footer';
import { siteConfig } from '@/config/site';
import '@/styles/globals.css';
import { FC } from 'react';

const inter = Inter({ subsets: ["latin"] });
const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
title: {
Expand All @@ -14,26 +15,23 @@ export const metadata: Metadata = {
},
description: siteConfig.description,
icons: {
icon: "/favicon.ico",
shortcut: "/favicon.ico",
apple: "/favicon.ico",
icon: '/favicon.ico',
shortcut: '/favicon.ico',
apple: '/favicon.ico',
},
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const RootLayout: FC<{ children: React.ReactNode }> = ({ children }) => {
return (
<html lang="en">
<html lang='en'>
<body className={inter.className}>
<div className="relative flex flex-col h-screen">
<div className='relative flex flex-col h-screen'>
<Header />
<main className="container mx-auto px-12 flex-grow">{children}</main>
<main className='container mx-auto px-12 flex-grow'>{children}</main>
<Footer />
</div>
</body>
</html>
);
}
};
export default RootLayout;
24 changes: 12 additions & 12 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
"use client";
import { Toaster } from "react-hot-toast";
import Hero from "@/components/hero";
import { useState } from "react";
import Uploader from "@/components/uploader";
import { ColorInfo } from "@/types/uploader";
import ColorList from "@/components/color-list";
'use client';
import { Toaster } from 'react-hot-toast';
import Hero from '@/components/hero';
import { FC, useState } from 'react';
import Uploader from '@/components/uploader';
import { ColorInfo } from '@/types/uploader';
import ColorList from '@/components/color-list';

const Home = () => {
const Home: FC = () => {
const [colorPalette, setColorPalette] = useState<ColorInfo[] | null>(null);

const onImageSelect = (colors: ColorInfo[]) => {
const onImageSelect = (colors: ColorInfo[]): void => {
setColorPalette(colors);
};

return (
<section>
<Hero />

<div className="hero-content text-center">
<div className="max-w-2xl">
<div className='hero-content text-center'>
<div className='max-w-2xl'>
<Uploader onImageSelect={onImageSelect} />
<ColorList colorPalette={colorPalette} />
</div>
</div>

<Toaster position="bottom-left" reverseOrder={false} />
<Toaster position='bottom-left' reverseOrder={false} />
</section>
);
};
Expand Down
42 changes: 14 additions & 28 deletions components/color-list/index.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
import toast from "react-hot-toast";
import {
ActiveColorBox as ColorBox,
InactiveColorBox,
} from "@/components/colorbox";
import { ColorInfo } from "@/types/uploader";
import { MaxPaletteSize } from "@/constants";
import toast from 'react-hot-toast';
import { ActiveColorBox as ColorBox, InactiveColorBox } from '@/components/colorbox';
import { ColorInfo } from '@/types/uploader';
import { MaxPaletteSize } from '@/constants';
import { FC } from 'react';

type Props = {
colorPalette: ColorInfo[] | null;
};

const ColorList = ({ colorPalette }: Props) => {
const ColorList: FC<Props> = ({ colorPalette }) => {
const handleOnCopyToClipboard = (selectedColor: string): void => {
navigator.clipboard.writeText(selectedColor ?? "");
toast.success("Copied to clipboard");
navigator.clipboard.writeText(selectedColor ?? '');
toast.success('Copied to clipboard');
};

const InactivePanel = () => {
const InactivePanel: FC = () => {
const boxes = Array.from({ length: MaxPaletteSize }, (_, index) => (
<InactiveColorBox key={index} />
));

return (
<div className="flex flex-row justify-around flex-wrap gap-2">
{boxes}
</div>
);
return <div className='flex flex-row justify-around flex-wrap gap-2'>{boxes}</div>;
};

const ActivePanel = () => {
const ActivePanel: FC = () => {
const boxes = (colorPalette || [])
.slice(0, MaxPaletteSize)
.map((colorInfo, index) => (
Expand All @@ -39,20 +33,12 @@ const ColorList = ({ colorPalette }: Props) => {
/>
));

return (
<div className="flex flex-row justify-around flex-wrap gap-2">
{boxes}
</div>
);
return <div className='flex flex-row justify-around flex-wrap gap-2'>{boxes}</div>;
};

return (
<div className="pt-14">
{colorPalette && colorPalette?.length > 0 ? (
<ActivePanel />
) : (
<InactivePanel />
)}
<div className='pt-14'>
{colorPalette && colorPalette?.length > 0 ? <ActivePanel /> : <InactivePanel />}
</div>
);
};
Expand Down
12 changes: 6 additions & 6 deletions components/colorbox/active.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import ProhibitIcon from "../icons/prohibit";
import { FC } from 'react';

type Props = {
color: string;
handleOnCopyToClipboard: (color: string) => void;
};

const ColorBox = ({ color, handleOnCopyToClipboard }: Props) => {
const ColorBox: FC<Props> = ({ color, handleOnCopyToClipboard }) => {
return (
<div
className="bg-transparent p-1 w-12 h-12 md:w-28 md:h-28 lg:w-28 lg:h-28 rounded-lg shadow-xl border-2 border-gray-300 border-dashed"
onClick={() => {
className='bg-transparent p-1 w-12 h-12 md:w-28 md:h-28 lg:w-28 lg:h-28 rounded-lg shadow-xl border-2 border-gray-300 border-dashed'
onClick={(): void => {
handleOnCopyToClipboard(color);
}}
>
<div
className="transform active:scale-y-75 transition-transform cursor-pointer flex flex-col justify-end h-full rounded-lg p-0"
className='transform active:scale-y-75 transition-transform cursor-pointer flex flex-col justify-end h-full rounded-lg p-0'
style={{
backgroundColor: color,
}}
>
<p className="p-2 rounded-b-lg rounded-none w-full text-white text-xs md:text-sm hidden md:block">
<p className='p-2 rounded-b-lg rounded-none w-full text-white text-xs md:text-sm hidden md:block'>
{color}
</p>
</div>
Expand Down
14 changes: 8 additions & 6 deletions components/colorbox/disabled.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import ProhibitIcon from "../icons/prohibit";
import { FC } from 'react';
import ProhibitIcon from '../icons/prohibit';

type Props = {
color?: string;
};

const Disabled = ({ color = "#E5E5E5" }: Props) => {
const backgroundColor = `bg-[${color}]`;

const Disabled: FC<Props> = ({ color = '#E5E5E5' }) => {
return (
<div className="bg-transparent p-1 w-12 h-12 md:w-28 md:h-28 lg:w-28 lg:h-28 rounded-lg shadow-xl border-2 border-gray-300 border-dashed">
<div className='bg-transparent p-1 w-12 h-12 md:w-28 md:h-28 lg:w-28 lg:h-28 rounded-lg shadow-xl border-2 border-gray-300 border-dashed'>
<div
className={`cursor-not-allowed flex flex-col justify-center items-center h-full rounded-lg p-0 ${backgroundColor}`}
className='cursor-not-allowed flex flex-col justify-center items-center h-full rounded-lg p-0'
style={{
backgroundColor: color,
}}
>
<ProhibitIcon />
</div>
Expand Down
4 changes: 2 additions & 2 deletions components/colorbox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { default as ActiveColorBox } from "./active";
export { default as InactiveColorBox } from "./disabled";
export { default as ActiveColorBox } from './active';
export { default as InactiveColorBox } from './disabled';
6 changes: 4 additions & 2 deletions components/footer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { FC } from 'react';

type Props = {};

const Footer = (props: Props) => {
const Footer: FC<Props> = () => {
return (
<footer className="footer footer-center p-4 text-base-content pt-12">
<footer className='footer footer-center p-4 text-base-content pt-12'>
<aside>
<p>Made with 💖 by Gimnath</p>
</aside>
Expand Down
19 changes: 10 additions & 9 deletions components/header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import GithubIcon from "../icons/github";
import { FC } from 'react';
import GithubIcon from '../icons/github';

type Props = {};

const Header = ({}: Props) => {
const Header: FC<Props> = ({}) => {
return (
<div className="navbar flex h-16 max-w-screen-xl items-center justify-between xl:mx-auto">
<div className="flex-1">
<div className="flex cursor-pointer text-2xl font-semibold">
🌈 Rainbow <span className="text-[#4ED1A5] ml-1"> Riot</span>
<div className='navbar flex h-16 max-w-screen-xl items-center justify-between xl:mx-auto'>
<div className='flex-1'>
<div className='flex cursor-pointer text-2xl font-semibold'>
🌈 Rainbow <span className='text-[#4ED1A5] ml-1'> Riot</span>
</div>
</div>
<div className="flex-none">
<label className="btn btn-ghost btn-circle">
<div className="indicator">
<div className='flex-none'>
<label className='btn btn-ghost btn-circle'>
<div className='indicator'>
<GithubIcon />
</div>
</label>
Expand Down
Loading

0 comments on commit 038c559

Please sign in to comment.