Commit c5835dbc by Sakilesh J

json server id error

parents
{
"path": "cz-conventional-changelog"
}
/node_modules
/build
/.git
/.next
README.md
Dockerfile
*.log
*.log*
.vscode
.DS_Store
.gitignore
.editorconfig
.env
.env.local
.gitlab-ci.yml
.eslintrc.js
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
\ No newline at end of file
NEXT_PUBLIC_API_URL=http://192.168.1.161:4000/
\ No newline at end of file
{
"extends": [
"next/core-web-vitals",
"plugin:storybook/recommended"
]
}
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
# yarn
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
{
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS --extends @commitlint/config-conventional",
"pre-commit": "pretty-quick --staged"
}
}
{
"jsxBracketSameLine": true,
"singleQuote": true,
"jsxSingleQuote": false,
"trailingComma": "none"
}
import type { StorybookConfig } from '@storybook/nextjs';
import path from 'path';
const config: StorybookConfig = {
stories: ['../components/**/*.stories.@(ts|tsx|js|jsx|mdx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-onboarding',
'@storybook/addon-interactions'
],
webpackFinal: async (config) => {
if (config.resolve) {
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, '../')
};
}
return config;
},
framework: {
name: '@storybook/nextjs',
options: {}
},
docs: {
autodocs: 'tag'
}
};
export default config;
import '@/styles/globals.css';
import type { Preview } from '@storybook/react';
import * as NextImage from 'next/image';
import { ImageProps } from 'next/image';
const preview: Preview = {
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i
}
}
}
};
export default preview;
Object.defineProperty(NextImage, 'getImageProps', {
configurable: true,
value: (props: ImageProps) => {
return { props: { ...props, srcSet: props.src } };
}
});
nodeLinker: node-modules
# Nextjs Starter Template
## Tools Configured
- Next.js
- React Storybook
- Typescript
- Tailwind CSS
- pnpm
- Commitizen
- Editorconfig
- Eslint
- Prettier
- Husky (to lint commit messages)
## Important Notes
- Enable nodejs corepack `corepack enable`
- Install pnpm using `corepack prepare pnpm@latest --activate`
- Install dependencies using `pnpm install`
- Install commitizen globally `npm install -g commitizen`
- Then, use `git cz` or `cz` to commit changes
- Commit messages must follow [angular conventional commit
standards](https://github.com/conventional-changelog/commitlint)
- Install prettier extension in editor. Enable "Format on save" option.
- Install editorconfig extension in editor.
- All files will be formatted using prettier before commit
### Development Server
```bash
pnpm dev
```
### Build Task
```bash
pnpm build
```
### Production Server
```bash
pnpm start
```
### Run Storybook
```bash
pnpm storybook
```
### Build Static Storybook
```bash
pnpm build-storybook
```
import Button from '@/components/base/Button/Button';
const AnotherPage = () => {
return (
<div className="container m-auto">
<center className="p-10">
<h3 className="text-3xl text-gray-600 font-semibold mb-5 px-5">
You&lsquo;ve landed on another page
</h3>
<Button href="/" size="lg">
Navigate home page
</Button>
</center>
</div>
);
};
export default AnotherPage;
import '@/styles/globals.css';
interface LayoutProps {
children: React.ReactNode;
}
export default function RootLayout({ children }: LayoutProps) {
return (
<html>
<head>
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link rel="icon" href="/favicon.ico" />
</head>
<body>{children}</body>
</html>
);
}
import PageNotFound from '@/components/layout/PageNotFound/index';
export default PageNotFound;
import Todo from "@/pages/Todo";
const HomePage = () => {
return (
<>
{
<Todo />
}
</>
);
};
export default HomePage;
"use client"
import React, { useState } from "react"
import Button from "@/components/base/Button/Button"
import Input from "@/components/base/input/Input"
import styles from "./form.module.css"
interface FormProps {
handleSubmit: (data: any) => Promise<void>;
}
const FormComponent: React.FC<FormProps> = ({ handleSubmit }) => {
const [input, setinput] = useState('')
const [isError, setisError] = useState(false)
const onSubmit = (e: React.SyntheticEvent) => {
e.preventDefault();
console.log(e)
if (input === '') {
setisError(true)
return
}
handleSubmit(input)
}
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setinput(e.target.value)
if (isError) {
setisError(false)
}
}
return (
<form className={styles.form} onSubmit={onSubmit}>
<div className={styles.iwrapper}>
<Input placeholder="Enter Item..."
onChange={handleChange} ErrorMessage={isError ? "Enter the Field" : undefined} />
</div>
<div className={styles.bwrapper}>
<Button size="sm" >
Submit
</Button>
</div>
</form>
)
}
export default FormComponent
\ No newline at end of file
.form {
display: flex;
padding: 20px;
width: 100%;
flex-wrap: wrap;
gap: 15px;
background-color: white;
}
.iwrapper {
min-width: 80%;
max-height: 50px;
flex: 1;
}
.iwrapper>input {
width: 100%;
}
.bwrapper>button {
min-width: 100%;
}
.bwrapper {
min-width: auto;
flex: 1;
}
\ No newline at end of file
import { Meta, StoryObj } from "@storybook/react";
import FormComponent from "./FormComponent";
import { fn } from "@storybook/test";
const meta: Meta<typeof FormComponent> = {
title: "Top-Level/Form",
component: FormComponent,
}
export default meta;
type story = StoryObj<typeof meta>
export const Form: story = {
args: {
handleSubmit: fn()
}
}
\ No newline at end of file
"use client"
import React, { useEffect, useState } from 'react'
import styles from './item.module.css'
import Input from '@/components/base/input/Input';
import closeIcon from '@/public/icons/red-x-10333.svg';
import Image from 'next/image';
export interface ItemProps {
id: number;
task: string;
isCompleted: boolean;
onClose: (id: number) => void;
updateTask: (id: number, task: string, isCompleted: boolean) => void;
}
const Item: React.FC<ItemProps> = ({ task, isCompleted, onClose, updateTask, id }) => {
const [isChecked, setisChecked] = useState(isCompleted)
useEffect(() => {
setisChecked(isCompleted)
}, [isCompleted])
const handleChange = async () => {
const res: any = await updateTask(id, task, !isCompleted)
if (res) {
setisChecked(!isChecked)
}
}
const handleItem = (e: React.ChangeEvent<HTMLInputElement>) => {
updateTask(id, e.target.value, isCompleted)
}
const handleClose = () => {
onClose(id)
}
return (
<div className={styles.items}>
<input type='checkbox' checked={isChecked} onChange={handleChange} className={styles.checkbox} />
<Input placeholder='Enter item...' defaultValue={task} onBlur={handleItem} style={{
border: 'none',
boxShadow: 'none',
padding: 0,
color: 'gray',
fontSize: '18px',
textDecoration: isChecked ? 'line-through' : ''
}} />
<div className={styles.actions} onClick={handleClose} >
<Image src={closeIcon} alt="" width={22} height={22} className={styles.closeIcon} />
</div>
</div>
)
}
export default Item
\ No newline at end of file
.items {
display: flex;
border-bottom: .01px solid rgb(236, 231, 231);
padding: 10px 20px;
gap: 10px;
align-items: center;
flex-direction: row;
padding: 20px;
width: 100%;
}
.checkbox {
width: 18px;
height: 18px;
/* outline: 1px solid black; */
}
.actions {
margin-left: auto;
min-width: 1.3rem;
min-height: 1.3rem;
cursor: pointer;
background-color: #cccccd;
border-radius: 100%;
display: flex;
justify-content: center;
align-items: center;
/* padding-top: 3px; */
}
.actions:hover {
background-color: rgb(165, 160, 160);
}
.closeIcon {
font-weight: 700;
width: .6rem;
height: .6rem;
object-fit: contain;
}
\ No newline at end of file
import { Meta, StoryObj } from "@storybook/react";
import Item from "./Item";
import { fn } from "@storybook/test";
const meta: Meta<typeof Item> = {
title: "Top-Level",
component: Item,
argTypes: {
id: {
control: {
type: 'text'
}
}
}
}
export default meta;
type story = StoryObj<typeof meta>
export const Item_: story = {
args: {
id: '1',
isCompleted: true,
task: 'Buy groceries',
onComplete: fn(),
onChange: fn(),
onClose: fn()
},
}
import type { Meta, StoryObj } from '@storybook/react';
import Button from './Button';
const meta: Meta<typeof Button> = {
title: 'Basic/Button',
component: Button,
tags: ['autodocs']
};
export default meta;
type Story = StoryObj<typeof meta>;
// interface TemplateProps {
// variant: 'primary' | 'light' | 'dark';
// }
const Template = () => {
return (
<div >
<h6 className="mb-2 font-semibold">Size</h6>
<div className="flex gap-5 mb-4 flex-wrap items-center">
<Button size="sm">
Small button
</Button>
<Button >Medium button</Button>
<Button href="/" size="sm">
Small Anchor
</Button>
<Button href="/">
Medium Anchor
</Button>
<Button size="sm" >
Small Outline
</Button>
<Button >
Medium Outline
</Button>
</div>
<h6 className="mb-2 font-semibold">Loading</h6>
<div className="flex gap-5 mb-4 flex-wrap items-center">
<Button size="sm" loading>
Small button
</Button>
<Button loading>
Medium button
</Button>
<Button href="/" size="sm" loading>
Small Anchor
</Button>
<Button href="/" loading>
Medium Anchor
</Button>
<Button size="sm" loading >
Small Outline
</Button>
<Button loading >
Medium Outline
</Button>
</div>
<h6 className="mb-2 font-semibold">Disabled</h6>
<div className="flex gap-5 mb-4 flex-wrap items-center">
<Button size="sm" disabled>
Small button
</Button>
<Button disabled>
Medium button
</Button>
<Button size="sm" disabled >
Small Outline
</Button>
<Button disabled >
Medium Outline
</Button>
</div>
<h6 className="mb-2 font-semibold">Disabled & Loading</h6>
<div className="flex gap-5 mb-4 flex-wrap items-center">
<Button size="sm" loading disabled>
Small button
</Button>
<Button loading disabled>
Medium button
</Button>
<Button size="sm" disabled loading >
Small Outline
</Button>
<Button disabled loading >
Medium Outline
</Button>
</div>
<h6 className="mb-2 font-semibold">Multiline</h6>
<div className="flex gap-5 mb-4 flex-wrap items-center">
<Button size="sm">
Lorem ipsum dolor sit <br /> amet consectetur adipisicing elit. <br />{' '}
Quas exercitationem unde voluptate iure dolore laudantium.
</Button>
<Button >
Lorem ipsum dolor sit amet consectetur adipisicing elit. <br /> Quas
exercitationem unde voluptate iure dolore laudantium.
</Button>
</div>
<br />
<div className="flex gap-5 mb-4 flex-wrap items-center">
<Button size="sm" loading>
Lorem ipsum dolor sit <br /> amet consectetur adipisicing elit. <br />{' '}
Quas exercitationem unde voluptate iure dolore laudantium.
</Button>
<Button loading>
Lorem ipsum dolor sit amet consectetur adipisicing elit. <br /> Quas
exercitationem unde voluptate iure dolore laudantium.
</Button>
</div>
<h6 className="mb-2 font-semibold">Block</h6>
<div className="flex flex-col gap-5">
<Button size="sm" >
Small button
</Button>
<Button >
Medium button
</Button>
<Button size="sm" loading>
Small button
</Button>
<Button loading>
Medium button
</Button>
<Button size="sm" loading disabled>
Small button
</Button>
<Button loading disabled>
Medium button
</Button>
</div>
</div>
);
};
export const primary: Story = {
render: () => (
<Template />
)
}
\ No newline at end of file
import Link from 'next/link';
import style from "./button.module.css"
interface ButtonProps extends React.HTMLAttributes<HTMLElement> {
variant?: 'primary' | 'light' | 'dark';
size?: 'sm' | 'md';
loading?: boolean;
disabled?: boolean;
href?: string;
children: React.ReactNode;
}
export default function Button({
variant = 'primary',
size = 'md',
loading = false,
disabled = false,
href,
children,
...rest
}: ButtonProps) {
// const classNames = cn(
// 'inline-flex items-center font-medium uppercase focus:outline-none',
// {
// /** backgrounds */
// 'bg-gray-200': disabled,
// 'bg-primary text-light shadow-primary':
// !disabled && !outline && variant === 'primary',
// 'bg-light text-dark shadow-light':
// !disabled && !outline && variant === 'light',
// 'bg-dark text-light shadow-dark':
// !disabled && !outline && variant === 'dark',
// /** outline */
// 'text-primary border-current border shadow-primary':
// !disabled && outline && variant === 'primary',
// 'text-light border-current border shadow-light':
// !disabled && outline && variant === 'light',
// 'text-dark border-current border shadow-dark':
// !disabled && outline && variant === 'dark',
// /** text */
// 'text-gray-400': disabled,
// /* size */
// 'text-sm px-8 py-3': size === 'sm',
// 'text-base px-9 py-3': size === 'md',
// /** block */
// 'w-full justify-center': block,
// /** hover, focus & active */
// 'hover:shadow-xl focus:shadow-glow active:translate-y-0.5': !disabled
// }
// );
const classNames = `${style.btn} ${size === 'sm' ? style.sm : style.md}`
return typeof href === 'string' ? (
<Link href={href} className={classNames} {...rest}>
{children}
{loading && <Loader />}
</Link>
) : (
<button disabled={disabled} className={classNames} {...rest}>
{children}
{loading && <Loader />}
</button>
);
}
export function Loader() {
return (
<span className={style.loader}>
</span>
);
}
.btn {
padding: 15px 20px;
background-color: white;
border: 1px solid rgb(189, 189, 189);
font-family: sans-serif;
border-radius: 5px;
cursor: pointer;
color: rgb(46, 46, 46);
min-width: 7.5rem;
display: flex;
gap: 10px;
justify-content: center;
align-items: center;
}
.btn:hover {
background-color: rgb(240, 242, 243);
}
.loader {
border-radius: 50%;
width: 30px;
height: 30px;
border: 5px solid transparent;
border-bottom: 5px solid black;
padding: 10px;
animation: loader infinite 1s linear;
}
.sm {
font-size: 16px;
}
.md {
font-size: 22px;
}
@keyframes loader {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
\ No newline at end of file
export { default } from './Button';
import { Meta, StoryObj } from "@storybook/react";
import Heading from "./Heading";
const meta: Meta<typeof Heading> = {
title: "Basic/Header",
component: Heading,
argTypes: {
count: { count: 'number' }
},
}
export default meta;
type story = StoryObj<typeof Heading>
export const Header: story = {
args: {
count: 1,
}
}
\ No newline at end of file
import React from 'react'
import styles from "./heading.module.css"
interface HeadingProps {
count: number;
}
const Heading: React.FC<HeadingProps> = ({ count }) => {
return (
<div className={styles.heading}>You have {count != 0 ? count : "no"} Todos</div>
)
}
export default Heading
\ No newline at end of file
.heading {
font-size: 25px;
font-weight: 700;
letter-spacing: 1px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
padding: 15px;
box-shadow: 0px 2px 4px rgba(0, 0, 0, .07);
text-align: center;
background-color: white;
}
\ No newline at end of file
import { Meta, StoryObj } from "@storybook/react";
import Input from "./Input";
import { fn } from "@storybook/test";
const meta: Meta<typeof Input> = {
component: Input,
title: "Basic/Input",
tags: ["autodocs"]
}
export default meta
type story = StoryObj<typeof meta>;
export const Primary: story = {
args: {
placeholder: 'Enter the value...',
onChange: fn(),
},
render: (args) => {
return <>
<p>Without Error</p>
<Input {...args} />
<p>With Error</p>
<Input {...args} ErrorMessage="Enter the Fields" />
</>
}
}
import React from "react"
import styles from "./input.module.css"
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
ErrorMessage?: string
}
const Input: React.FC<InputProps> = ({ ErrorMessage, ...props }) => {
return (
<>
<input {...props} className={`${styles.input} ${ErrorMessage
&& styles.inputError}`} />
{
ErrorMessage &&
<div className={styles.error}>
{ErrorMessage}
</div>
}
</>
)
}
export default Input
\ No newline at end of file
.input {
padding: 15px 20px;
border-radius: 5px;
border: 2px solid #d2d2d2;
font-size: 15px;
box-shadow: inset 0px 3px 4px #f3f3f3;
font-family: sans-serif;
width: 100%;
}
.input::placeholder {
font-size: 15px;
}
.input:focus {
outline: none;
border: 2px solid rgb(189, 189, 189);
}
.strike {
text-decoration: line-through;
}
.error {
color: red;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
padding: 10px;
font-size: 13px;
}
.inputError {
border: 1px solid red;
}
.invisible {
padding-inline: 0px;
border: none;
font-size: 16px;
color: gray;
background-color: transparent;
box-shadow: none;
padding-block: 10px;
}
.invisible::placeholder {
font-size: 18px;
}
.invisible:focus {
outline: none;
border: none;
}
\ No newline at end of file
export default {
title: 'Basic/Typography'
};
export const TitleAndParagraph = () => (
<div className="container">
<div className="flex flex-col gap-4 mb-5">
<div className="text-9xl font-bold uppercase">Heading</div>
<div className="text-8xl font-bold uppercase">Heading</div>
<div className="text-7xl font-bold uppercase">Heading</div>
<div className="text-6xl font-bold uppercase">Heading</div>
<div className="text-5xl font-bold uppercase">Heading</div>
<div className="text-4xl font-bold uppercase">Heading</div>
<div className="text-3xl font-bold uppercase">Heading</div>
<div className="text-2xl font-bold uppercase">Heading</div>
<div className="text-xl font-bold uppercase">Heading</div>
</div>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo et quae
consequuntur voluptatum quibusdam, autem velit quidem laborum, dignissimos
doloremque ullam eos fugit repellendus maiores eveniet repellat dolor eius
perspiciatis? Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
<p>
Quasi aliquam impedit magnam tempora doloribus voluptatibus, at ea dolores
facilis et quod hic, cumque repellendus quidem expedita explicabo
architecto, possimus minima!
</p>
</div>
);
import Item from "@/components/Top-Level/Item/Item";
import styles from "./list.module.css";
interface ListItemProps {
data: {
id: number;
task: string;
isCompleted: boolean;
}[];
onClose: (id: number) => void;
updateTask: (id: number, task: string, isCompleted: boolean) => void;
}
const ListItem: React.FC<ListItemProps> = ({ data, updateTask, onClose }) => {
return (
<div className={styles.list}>
{
data.map((item) => {
return (
<Item
key={item.id}
{...item}
updateTask={updateTask}
onClose={onClose}
/>
)
})
}
</div>);
}
export default ListItem;
\ No newline at end of file
.list {
display: flex;
flex-direction: column;
width: 100%;
margin-top: 5px;
}
.list> :nth-last-child(1) {
border-bottom: none;
}
\ No newline at end of file
import type { Meta, StoryObj } from '@storybook/react';
import List from './List';
import { List_data } from '@/utils/data';
import { fn } from '@storybook/test';
import Heading from '@/components/base/Heading/Heading';
import FormComponent from '@/components/Top-Level/Form/FormComponent';
const meta: Meta<typeof List> = {
title: 'Layout',
component: List,
};
export default meta;
type Story = StoryObj<typeof meta>;
export const List_: Story = {
args: {
data: List_data,
onChange: fn(),
onClose: fn(),
onComplete: fn()
}
};
export const Todos: Story = {
args: {
data: List_data,
onChange: fn(),
onClose: fn(),
onComplete: fn()
},
// parameters: {
// layout: 'centered',
// },
render: (args) => (
<div style={{
display: 'flex',
justifyContent: 'center',
flexShrink: 1,
width: '100%',
}}>
<div style={{
boxShadow: '2px 2px 3px rgba(0,0,0,0.06), -2px -2px 3px rgba(0,0,0,0.06)',
flexBasis: '100%',
maxWidth: '600px',
flexGrow: 1,
}}>
<Heading count={args.data.length} />
<List {...args} />
<FormComponent handleSubmit={fn()} />
</div>
</div>
)
}
\ No newline at end of file
import type { Meta, StoryObj } from '@storybook/react';
import PageNotFoundComponent from './PageNotFound';
const meta: Meta<typeof PageNotFoundComponent> = {
title: 'Layout/Page Not Found',
component: PageNotFoundComponent,
parameters: {
layout: 'centered'
}
};
export default meta;
type Story = StoryObj<typeof meta>;
export const PageNotFound: Story = {};
import Image from 'next/image';
import Button from '@/components/base/Button';
import FourOhFour from './img/404.png';
export default function PageNotFound() {
return (
<div className="flex flex-col justify-center items-center">
<Image src={FourOhFour} alt="404, Page Not Found!" />
<Button href="/">Back to Home</Button>
</div>
);
}
export { default } from './PageNotFound';
@use '@styles/vars.scss';
.notFound {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10vh 1em;
box-sizing: border-box;
h2 {
font-size: 10em;
font-weight: 100;
line-height: 0.8;
margin: 0;
color: #1ea7fd;
}
a {
margin-top: 2em;
}
}
@include vars.mQuery(xl) {
.notFound {
font-size: 0.9em;
}
}
import ResponsiveImage from './ResponsiveImage';
import type { ResponsiveImageProps } from './ResponsiveImage';
export default {
title: 'Shared/ResponsiveImage',
component: ResponsiveImage,
parameters: {
layout: 'fullscreen'
},
tags: ['autodocs']
};
export const Image = {
args: {
src: 'https://dummyimage.com/1920x570',
width: 1920,
height: 570,
sizes: '100vw'
}
};
export const ArtDirection = {
args: {
src: 'https://dummyimage.com/576x540',
width: 576,
height: 540,
sizes: '100vw'
},
render: (args: ResponsiveImageProps) => (
<ResponsiveImage {...args}>
<ResponsiveImage.Source
media="xxl"
src="https://dummyimage.com/1920x540"
width={1920}
height={540}
sizes="100vw"
/>
<ResponsiveImage.Source
media="xl"
src="https://dummyimage.com/1536x540"
width={1536}
height={540}
sizes="100vw"
/>
<ResponsiveImage.Source
media="lg"
src="https://dummyimage.com/1280x540"
width={1280}
height={540}
sizes="100vw"
/>
<ResponsiveImage.Source
media="md"
src="https://dummyimage.com/1024x540"
width={1024}
height={540}
sizes="100vw"
/>
<ResponsiveImage.Source
media="sm"
src="https://dummyimage.com/768x540"
width={768}
height={540}
sizes="100vw"
/>
<ResponsiveImage.Source
media="(min-width: 576px)"
src="https://dummyimage.com/640x540"
width={640}
height={540}
sizes="100vw"
/>
</ResponsiveImage>
)
};
import { memo } from 'react';
import React from 'react';
import { getImageProps } from 'next/image';
import breakpoints from './breakpoints';
export type Image = {
url: string;
width: number;
height: number;
alternativeText?: string;
};
export interface ResponsiveImageProps
extends React.HTMLAttributes<HTMLImageElement> {
src: string;
width: number;
height: number;
sizes: string;
alt?: string;
priority?: boolean;
quality?: number;
children?: React.ReactNode;
}
export interface SourceProps extends React.HTMLAttributes<HTMLSourceElement> {
src: string;
width: number;
height: number;
media: string;
sizes: string;
quality?: number;
}
export const ResponsiveImage: React.FC<ResponsiveImageProps> & {
Source: React.FC<SourceProps>;
} = ({
src,
width,
height,
alt,
sizes,
quality,
priority,
children,
...rest
}) => {
if (src) {
const { props } = getImageProps({
src,
width,
height,
sizes,
quality,
priority,
alt: alt || ''
});
return (
<picture>
{children}
<img alt="" {...props} {...rest} />
</picture>
);
}
};
ResponsiveImage.Source = memo(
({ src, width, height, sizes, media, quality, ...rest }: SourceProps) => {
if (src) {
const query = breakpoints[media] || media;
const { props } = getImageProps({
width,
height,
src,
sizes,
quality,
alt: ''
});
return (
<source
media={query}
src={props.src}
srcSet={props.srcSet}
width={props.width}
height={props.height}
sizes={props.sizes}
{...rest}
/>
);
}
}
);
ResponsiveImage.displayName = 'ResponsiveImage';
ResponsiveImage.Source.displayName = 'ResponsiveImageSource';
export default ResponsiveImage;
type Breakpoints = {
[key: string]: string;
};
const breakpoints: Breakpoints = {
sm: '(min-width: 640px)',
md: '(min-width: 768px)',
lg: '(min-width: 1024px)',
xl: '(min-width: 1280px)',
xxl: '(min-width: 1536px)'
};
export default breakpoints;
export * from './ResponsiveImage';
import type { Meta, StoryObj } from '@storybook/react';
import ResponsiveVideoComponent from './ResponsiveVideo';
const meta: Meta<typeof ResponsiveVideoComponent> = {
title: 'Shared/ResponsiveVideo',
component: ResponsiveVideoComponent,
parameters: {
layout: 'centered'
},
tags: ['autodocs']
};
export default meta;
type Story = StoryObj<typeof meta>;
const autoPlayFallback = (
<h3 className="font-bold text-lg text-light bg-primary px-4 py-2">
Auto play failed. I am a fallback element
</h3>
);
export const ResponsiveVideo: Story = {
args: {
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4',
srcSet: [
{
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4',
media: '(min-width: 640px)'
}
],
autoPlayFallback,
autoPlay: true,
controls: true,
muted: true
}
};
export const AutoPlayFailed: Story = {
args: {
src: 'broken.mp4',
autoPlay: true,
autoPlayFallback
}
};
'use client';
import React, { useState, useEffect, useRef } from 'react';
import breakpoints from './breakpoints';
export interface ResponsiveVideoProps
extends React.VideoHTMLAttributes<HTMLVideoElement> {
src: string;
/** first match in the array will be selected
* media should be a valid media query or
* a key from breakpoints object
*/
srcSet?: {
src: string;
media: string;
}[];
/** auto plays video source */
autoPlay?: boolean;
/** If autoplay fails and if there is a fallback,
* display this fallback element */
autoPlayFallback?: React.ReactNode;
}
const ResponsiveVideo = ({
src,
srcSet,
autoPlay,
autoPlayFallback,
...rest
}: ResponsiveVideoProps) => {
const [isAutoPlayFailed, setIsAutoPlayFailed] = useState(false);
const [currentSrc, setCurrentSrc] = useState(src);
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
const handleResize = () => {
/** find the set that matches current media query */
const matchedSet = srcSet?.find(
({ media }) => window.matchMedia(breakpoints[media] || media).matches
);
/* set the current src to the matched set or the default src */
setCurrentSrc(matchedSet?.src || src);
};
/* call handleResize on mount */
handleResize();
/* add resize event listener to window */
window.addEventListener('resize', handleResize);
/* remove event listener on unmount */
return () => window.removeEventListener('resize', handleResize);
}, [src, srcSet]);
useEffect(() => {
async function play() {
try {
/** If user prefers reduced motion,
* throw an error and stop autoplay
*/
const prefersReducedMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
);
if (prefersReducedMotion.matches) {
throw new Error('User prefers reduced motion');
} else {
/* if autoplay is true, play the video */
autoPlay && (await videoRef?.current?.play());
}
} catch (error: any) {
/* AbortError happens when source is changed in runtime,
if error is not AbortError, mark autoPlay as failed
*/
if (error.name !== 'AbortError') {
console.error(error);
/* if play failed, report that autoplay has failed */
setIsAutoPlayFailed(true);
}
}
}
play();
}, [autoPlay, currentSrc]);
return isAutoPlayFailed && autoPlayFallback ? (
autoPlayFallback
) : (
<video ref={videoRef} src={currentSrc} {...rest} />
);
};
export default ResponsiveVideo;
type Breakpoints = {
[key: string]: string;
};
const breakpoints: Breakpoints = {
sm: '(min-width: 640px)',
md: '(min-width: 768px)',
lg: '(min-width: 1024px)',
xl: '(min-width: 1280px)',
xxl: '(min-width: 1536px)'
};
export default breakpoints;
export * from './ResponsiveVideo';
/** Commonly used types that are not
* associated with specific component */
export interface ILink {
label: string;
url: string;
}
export interface ISocialLink {
icon: string;
url: string;
label?: string;
}
export interface TodoListItems {
id: number;
task: string;
isCompleted: boolean;
}
\ No newline at end of file
export const SERVER_URL: string = process.env.NEXT_PUBLIC_API_URL || 'http://192.168.1.161:4000/'
\ No newline at end of file
{
"tasks": [
{
"id": "1",
"task": "clg",
"isCompleted": false
},
{
"id": "2",
"task": "new",
"isCompleted": true
},
{
"id": "3",
"task": "jake",
"isCompleted": false
},
{
"id": "4",
"task": "new",
"isCompleted": true
}
]
}
\ No newline at end of file
import { SERVER_URL } from "@/config/URL";
import axios from "axios";
export const Axios = axios.create(
{
baseURL: SERVER_URL,
timeout: 3000,
headers: {
"Content-Type": 'application/json',
Accept: 'application/json'
}
}
)
\ No newline at end of file
import { Axios } from "./Instance";
export default async function AddTask(task: string) {
try {
const res = await Axios.post('tasks', {
task, isCompleted: false
})
alert('Task added successfully')
return res.data
} catch (error) {
alert("something went wrong")
console.log(error)
return null;
}
}
export async function DeleteTask(id: number) {
try {
const isDelete = confirm('Are you sure you want to delete');
if (isDelete) {
const res = await Axios.delete(`tasks/${id}`)
return res.data
}
} catch (error) {
alert('something went wrong')
console.log(error)
return null;
}
}
export async function UpdateTask(id: number, task: string, isCompleted: boolean) {
try {
const res = await Axios.put(`/tasks/${id}`, {
task, isCompleted, id
})
return res.data
} catch (error) {
console.log(error)
alert("something went wrong")
return null;
}
}
import { Axios } from "./Instance";
export default async function getall() {
try {
const res = await Axios.get('tasks');
return await res.data
} catch (error) {
console.log(error)
return null
}
}
\ No newline at end of file
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 's3-ap-southeast-1.amazonaws.com'
}
],
imageSizes: [64, 128, 256, 576, 768, 992, 1200, 1600, 1920, 2048, 3840]
},
webpack: (config, { isServer }) => {
if (process.env.ANALYZE && !isServer) {
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'server',
analyzerPort: 8888,
openAnalyzer: true
})
);
}
return config;
},
async rewrites() {
return [
{
source: '/api/:path*',
destination: `${process.env.NEXT_PUBLIC_API_URL}/:path*`
}
];
},
poweredByHeader: false,
compress: false
};
{
"name": "nextjs-starter-template",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"serve": "json-server --watch db.json --port 4000 ",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"analyze": "cross-env ANALYZE=true next build"
},
"dependencies": {
"@types/node": "^20.11.5",
"@types/react": "^18.2.48",
"autoprefixer": "^10.4.17",
"axios": "^1.7.2",
"classnames": "^2.5.1",
"json-server": "^1.0.0-beta.0",
"next": "^14.1.0",
"postcss": "^8.4.33",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sharp": "^0.33.2",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3"
},
"devDependencies": {
"@commitlint/cli": "^18.4.4",
"@commitlint/config-conventional": "^18.4.4",
"@storybook/addon-essentials": "^7.6.10",
"@storybook/addon-interactions": "7.6.10",
"@storybook/addon-links": "^7.6.10",
"@storybook/addon-onboarding": "1.0.10",
"@storybook/blocks": "7.6.10",
"@storybook/nextjs": "^7.6.10",
"@storybook/react": "7.6.10",
"@storybook/test": "7.6.10",
"@types/eslint": "^8.56.2",
"cross-env": "^7.0.3",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.56.0",
"eslint-config-next": "^14.1.0",
"eslint-plugin-storybook": "^0.6.15",
"husky": "^8.0.3",
"prettier": "^3.2.4",
"pretty-quick": "^4.0.0",
"storybook": "^7.6.10",
"webpack-bundle-analyzer": "^4.10.1"
}
}
"use client"
import style from "./todoapp.module.css"
import { useState, useEffect } from "react";
import Heading from "@/components/base/Heading/Heading";
import List from "@/components/layout/List/List";
import FormComponent from "@/components/Top-Level/Form/FormComponent";
import { TodoListItems } from "@/components/types";
import AddTask, { UpdateTask, DeleteTask } from "@/lib/Operation";
import getall from "@/lib/getall";
interface StateTodo {
data?: TodoListItems[],
isError: boolean;
isLoading: boolean;
}
const Todo = () => {
const [refresh, setrefresh] = useState<boolean>(false)
const [TodoList, setTodoList] = useState<StateTodo>({
isError: false,
isLoading: true,
data: []
})
useEffect(() => {
(async () => {
setTodoList(
{
...TodoList,
isLoading: true,
}
)
const data = await getall();
if (data) {
setTodoList({
isError: false,
isLoading: false,
data
})
} else {
setTodoList({
...TodoList,
isLoading: false,
isError: true,
})
}
})()
}, [refresh])
const handleDelete = async (id: number) => {
const result = await DeleteTask(id)
if (result) {
setrefresh(!refresh)
}
}
const handleAdd = async (task: string) => {
const result = await AddTask(task)
if (result) {
setrefresh(!refresh)
}
}
if (TodoList.isLoading) {
return (<Wrapper>
<div className={style.loading} />
</Wrapper>)
}
if (TodoList.isError) {
return (
<Wrapper>
<h2 className={style.notFound}>Something went wrong</h2>
</Wrapper>
)
}
return (
<Wrapper>
{
TodoList.data &&
(
<>
<Heading count={TodoList.data.length} />
{
TodoList.data.length !== 0 &&
<List data={TodoList.data} onClose={handleDelete} updateTask={UpdateTask} />
}
<FormComponent handleSubmit={handleAdd} />
</>
)
}
</Wrapper>
);
}
export default Todo;
type WrapperProps = {
children: React.ReactNode;
}
const Wrapper: React.FC<WrapperProps> = ({ children }) => {
return (
<div className={style.container}>
<div className={style.todoWrapper}>
{children}
</div>
</div>
)
}
\ No newline at end of file
.container {
display: flex;
justify-content: center;
flex-shrink: 1;
width: 100%;
padding: 20px;
height: 100vh;
background: radial-gradient(circle, #b3b3b3 10%, transparent 11%), radial-gradient(circle at bottom left, #b3b3b3 5%, transparent 6%), radial-gradient(circle at bottom right, #b3b3b3 5%, transparent 6%), radial-gradient(circle at top left, #b3b3b3 5%, transparent 6%), radial-gradient(circle at top right, #b3b3b3 5%, transparent 6%);
background-size: 1em 1em;
}
.todoWrapper {
background-color: white;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.06), -2px -2px 3px rgba(0, 0, 0, 0.06);
flex-basis: 100%;
max-width: 600px;
flex-grow: 1;
height: min-content;
}
.loading {
width: 50px;
height: 50px;
padding: 20px;
border: 10px solid black;
border-bottom: 10px solid transparent;
animation: rotate 1s infinite linear;
border-radius: 100%;
margin: 10px;
margin-inline: auto;
}
.notFound {
padding: 10px;
text-align: center;
font-size: 25px;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg)
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
<defs>
</defs>
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
<path d="M 11 90 c -2.815 0 -5.63 -1.074 -7.778 -3.222 c -4.295 -4.296 -4.295 -11.261 0 -15.557 l 68 -68 c 4.297 -4.296 11.26 -4.296 15.557 0 c 4.296 4.296 4.296 11.261 0 15.557 l -68 68 C 16.63 88.926 13.815 90 11 90 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(253,254,254); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<path d="M 79 90 c -2.815 0 -5.63 -1.074 -7.778 -3.222 l -68 -68 c -4.295 -4.296 -4.295 -11.261 0 -15.557 c 4.296 -4.296 11.261 -4.296 15.557 0 l 68 68 c 4.296 4.296 4.296 11.261 0 15.557 C 84.63 88.926 81.815 90 79 90 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(253,254,254); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
</g>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 512 103.22"><path d="M340.36.04h89.18V16.5h-35.38v86.6h-17.69V16.5h-36.11V.04zM503.8 70.86c-.19-1.82-1.03-3.25-2.49-4.27-1.48-1.03-3.38-1.54-5.72-1.54-1.64 0-3.05.25-4.23.74-1.17.49-2.08 1.15-2.71 1.99-.62.84-.93 1.8-.96 2.87 0 .9.22 1.68.64 2.33.42.66.98 1.22 1.71 1.67.72.46 1.52.83 2.4 1.14.89.31 1.77.57 2.66.78l4.09 1c1.64.38 3.23.89 4.76 1.54 1.52.64 2.9 1.45 4.11 2.43 1.21.98 2.17 2.16 2.87 3.54.71 1.39 1.07 3.01 1.07 4.87 0 2.52-.65 4.73-1.95 6.64-1.31 1.9-3.19 3.39-5.66 4.46-2.46 1.07-5.43 1.61-8.93 1.61-3.38 0-6.33-.52-8.81-1.56-2.49-1.03-4.44-2.54-5.84-4.52-1.4-1.99-2.15-4.41-2.26-7.26h7.76c.11 1.49.59 2.73 1.41 3.74.82.99 1.9 1.72 3.22 2.22 1.33.48 2.82.73 4.46.73 1.71 0 3.22-.26 4.53-.77 1.29-.51 2.31-1.21 3.04-2.14.75-.9 1.12-1.98 1.13-3.21-.01-1.12-.35-2.05-.99-2.79-.66-.73-1.57-1.34-2.74-1.84-1.17-.49-2.54-.94-4.1-1.33l-4.96-1.25c-3.58-.91-6.42-2.3-8.5-4.15-2.08-1.86-3.11-4.31-3.11-7.39 0-2.53.69-4.75 2.1-6.65 1.39-1.9 3.29-3.38 5.7-4.43 2.42-1.06 5.15-1.58 8.2-1.58 3.09 0 5.8.52 8.14 1.58 2.33 1.05 4.17 2.51 5.5 4.38s2.02 4 2.06 6.42h-7.6zm-40.09-11.8h7.84v30.19c-.01 2.78-.61 5.15-1.79 7.15-1.18 2-2.83 3.52-4.93 4.59-2.1 1.07-4.56 1.61-7.35 1.61-2.55 0-4.84-.46-6.88-1.36-2.04-.9-3.66-2.24-4.84-4.01-1.2-1.78-1.79-3.98-1.79-6.63h7.85c.01 1.16.28 2.16.78 3 .5.84 1.2 1.48 2.08 1.93.9.45 1.94.67 3.1.67 1.26 0 2.33-.26 3.21-.79.87-.52 1.55-1.3 2.01-2.34.46-1.03.7-2.3.71-3.82V59.06zm-30.19 43.41c-1.3 0-2.4-.45-3.32-1.35-.92-.89-1.38-1.98-1.37-3.27-.01-1.25.45-2.32 1.37-3.22.92-.9 2.02-1.35 3.32-1.35 1.25 0 2.34.45 3.26 1.35.93.9 1.4 1.97 1.41 3.22-.01.85-.22 1.63-.66 2.33-.44.71-1 1.26-1.71 1.67-.7.41-1.46.62-2.3.62zm-329-.14L22.11 0H0v103.06h17.69V22.03l65.22 81.07h110.78V86.64H122.2v-27.2h57.49V42.98H122.2V16.5h71.49V.04h-89.18V16.5h.01v85.83zM261.98 73.7l-11.6-14.42-35.37 43.94h23.21l23.76-29.52zM238.22.09h-23.15l82.92 103.05h23.21l-41.46-51.49L321.14.16 297.99.2l-29.84 37.06L238.22.09z"/></svg>
<svg width="512" height="63.478" viewBox="0 0 512 63.478" xmlns="http://www.w3.org/2000/svg"><path d="M52.898 0C38.792 0 29.976 7.053 26.45 21.16c5.29-7.054 11.462-9.699 18.515-7.935 4.024 1.005 6.9 3.926 10.084 7.157 5.186 5.264 11.189 11.357 24.3 11.357 14.106 0 22.922-7.053 26.449-21.16-5.29 7.054-11.462 9.699-18.515 7.935-4.024-1.005-6.9-3.926-10.084-7.157C72.012 6.093 66.01 0 52.898 0zM26.45 31.739c-14.106 0-22.922 7.053-26.449 21.16 5.29-7.054 11.461-9.699 18.514-7.935 4.025 1.007 6.9 3.926 10.084 7.157 5.186 5.264 11.19 11.357 24.3 11.357 14.107 0 22.923-7.053 26.45-21.16-5.29 7.054-11.462 9.699-18.515 7.935-4.024-1.005-6.9-3.926-10.084-7.156-5.186-5.265-11.189-11.358-24.3-11.358z" fill="#38bdf8"/><path d="M158.687 26.747h-9.231v17.868c0 4.765 3.126 4.69 9.231 4.392v7.222c-12.358 1.489-17.272-1.936-17.272-11.614V26.747h-6.85v-7.743h6.85v-10l8.04-2.382v12.382h9.232zm35.192-7.743h8.04V56.23h-8.04v-5.36c-2.83 3.945-7.222 6.328-13.03 6.328-10.124 0-18.537-8.562-18.537-19.58 0-11.093 8.413-19.58 18.538-19.58 5.807 0 10.2 2.382 13.029 6.253zM182.115 49.53c6.7 0 11.764-4.989 11.764-11.912s-5.063-11.912-11.764-11.912-11.763 4.988-11.763 11.912 5.063 11.912 11.763 11.912zm33.205-36.11c-2.83 0-5.137-2.383-5.137-5.138a5.147 5.147 0 0 1 5.137-5.137 5.147 5.147 0 0 1 5.137 5.137c0 2.755-2.308 5.138-5.137 5.138zm-4.02 42.808V19.004h8.04V56.23zm17.346 0V1.881h8.041v54.348zm60.23-37.225h8.487L285.675 56.23h-7.892l-7.743-25.09-7.817 25.09h-7.891l-11.689-37.225h8.487l7.222 25.685 7.817-25.685h7.668l7.743 25.685zm18.464-5.583c-2.83 0-5.137-2.383-5.137-5.138a5.147 5.147 0 0 1 5.137-5.137 5.147 5.147 0 0 1 5.137 5.137c0 2.755-2.308 5.138-5.137 5.138zm-4.02 42.808V19.004h8.04V56.23zm36.926-38.193c8.339 0 14.295 5.659 14.295 15.337v22.856h-8.04V34.192c0-5.658-3.277-8.636-8.34-8.636-5.285 0-9.454 3.127-9.454 10.72V56.23h-8.04V19.004h8.04v4.765c2.457-3.871 6.477-5.733 11.54-5.733zM392.66 4.114h8.04V56.23h-8.04v-5.36c-2.83 3.945-7.222 6.328-13.029 6.328-10.125 0-18.538-8.562-18.538-19.58 0-11.093 8.413-19.58 18.538-19.58 5.807 0 10.2 2.382 13.029 6.253zM380.896 49.53c6.7 0 11.763-4.989 11.763-11.912s-5.063-11.912-11.763-11.912-11.763 4.988-11.763 11.912 5.062 11.912 11.763 11.912zm46.754 7.668c-11.242 0-19.654-8.562-19.654-19.58 0-11.093 8.412-19.58 19.654-19.58 7.296 0 13.625 3.796 16.603 9.603l-6.924 4.02c-1.638-3.498-5.286-5.732-9.753-5.732-6.552 0-11.54 4.988-11.54 11.689s4.988 11.688 11.54 11.688c4.467 0 8.115-2.308 9.902-5.732l6.923 3.945c-3.126 5.882-9.455 9.679-16.75 9.679zm30.003-27.919c0 6.775 20.027 2.68 20.027 16.454 0 7.445-6.477 11.465-14.517 11.465-7.445 0-12.806-3.35-15.188-8.71l6.924-4.021c1.191 3.35 4.169 5.36 8.264 5.36 3.573 0 6.328-1.19 6.328-4.169 0-6.626-20.027-2.903-20.027-16.23 0-6.998 6.03-11.39 13.624-11.39 6.105 0 11.168 2.828 13.773 7.742l-6.774 3.797c-1.34-2.903-3.946-4.244-6.999-4.244-2.903 0-5.435 1.266-5.435 3.946zm34.322 0c0 6.775 20.027 2.68 20.027 16.454 0 7.445-6.477 11.465-14.518 11.465-7.445 0-12.805-3.35-15.188-8.71l6.924-4.021c1.191 3.35 4.17 5.36 8.264 5.36 3.574 0 6.328-1.19 6.328-4.169 0-6.626-20.027-2.903-20.027-16.23 0-6.998 6.03-11.39 13.625-11.39 6.104 0 11.167 2.828 13.773 7.742l-6.775 3.797c-1.34-2.903-3.946-4.244-6.998-4.244-2.904 0-5.435 1.266-5.435 3.946z" fill="#0f172a"/></svg>
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="logo-typescript" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 283.09 69.57">
<g fill="#007ACC">
<path d="M34.98 7.56H20.43v45.07h-5.91V7.56H0V2.21h34.98V7.56z"/>
<path d="M57.94 16.63L41.38 58.39c-2.95 7.45-7.1 11.18-12.45 11.18 -1.5 0-2.75-0.15-3.76-0.46v-5.17c1.24 0.42 2.38 0.63 3.41 0.63 2.91 0 5.09-1.73 6.54-5.2l2.88-6.82L23.94 16.63h6.4l9.74 27.7c0.12 0.35 0.36 1.27 0.74 2.74h0.21c0.12-0.56 0.35-1.45 0.7-2.67l10.23-27.77H57.94z"/>
<path d="M67.37 47.43h-0.14v21.76h-5.77V16.63h5.77v6.33h0.14c2.84-4.78 6.98-7.17 12.45-7.17 4.64 0 8.26 1.61 10.86 4.83 2.6 3.22 3.9 7.54 3.9 12.96 0 6.02-1.46 10.85-4.39 14.47 -2.93 3.62-6.94 5.43-12.02 5.43C73.5 53.47 69.9 51.46 67.37 47.43zM67.23 32.91v5.03c0 2.98 0.97 5.5 2.9 7.58s4.39 3.11 7.37 3.11c3.49 0 6.23-1.34 8.21-4.01 1.98-2.67 2.97-6.39 2.97-11.14 0-4.01-0.93-7.15-2.78-9.42 -1.85-2.27-4.36-3.41-7.52-3.41 -3.35 0-6.05 1.17-8.09 3.5C68.25 26.47 67.23 29.39 67.23 32.91z"/>
<path d="M129.56 36.07h-25.42c0.09 4.01 1.17 7.1 3.23 9.28 2.06 2.18 4.9 3.27 8.51 3.27 4.05 0 7.78-1.34 11.18-4.01v5.41c-3.16 2.3-7.35 3.45-12.55 3.45 -5.09 0-9.08-1.63-11.99-4.9 -2.91-3.27-4.36-7.87-4.36-13.8 0-5.6 1.59-10.17 4.76-13.69 3.18-3.53 7.12-5.29 11.83-5.29s8.35 1.52 10.93 4.57c2.58 3.05 3.87 7.28 3.87 12.69V36.07zM123.65 31.18c-0.02-3.33-0.83-5.92-2.41-7.77 -1.58-1.85-3.78-2.78-6.59-2.78 -2.72 0-5.03 0.97-6.93 2.92 -1.9 1.95-3.07 4.49-3.52 7.63H123.65z"/>
<path d="M134.6 50.59v-6.96c0.73 0.7 1.6 1.34 2.62 1.9 1.02 0.56 2.09 1.04 3.22 1.42s2.26 0.69 3.39 0.9c1.14 0.21 2.19 0.32 3.15 0.32 3.32 0 5.81-0.67 7.45-2.02 1.64-1.35 2.46-3.29 2.46-5.82 0-1.36-0.27-2.54-0.82-3.55 -0.55-1.01-1.3-1.93-2.27-2.76s-2.11-1.63-3.43-2.39c-1.32-0.76-2.74-1.56-4.26-2.41 -1.61-0.89-3.11-1.79-4.5-2.71 -1.39-0.91-2.61-1.92-3.63-3.02 -1.03-1.1-1.84-2.35-2.43-3.74 -0.59-1.39-0.88-3.03-0.88-4.9 0-2.3 0.46-4.29 1.38-5.99 0.92-1.7 2.13-3.1 3.64-4.2 1.5-1.1 3.21-1.92 5.13-2.46 1.92-0.54 3.88-0.81 5.87-0.81 4.55 0 7.86 0.6 9.94 1.79v6.64c-2.72-2.06-6.22-3.09-10.49-3.09 -1.18 0-2.36 0.14-3.54 0.4 -1.18 0.27-2.23 0.71-3.15 1.32 -0.92 0.61-1.67 1.39-2.25 2.36 -0.58 0.96-0.87 2.13-0.87 3.52 0 1.29 0.22 2.4 0.66 3.34 0.44 0.94 1.09 1.79 1.95 2.57 0.86 0.77 1.9 1.52 3.14 2.25 1.23 0.73 2.65 1.52 4.26 2.39 1.65 0.89 3.22 1.83 4.7 2.81s2.78 2.07 3.89 3.27c1.11 1.2 2 2.52 2.65 3.97 0.65 1.45 0.98 3.12 0.98 4.99 0 2.48-0.45 4.59-1.33 6.31 -0.89 1.72-2.09 3.12-3.6 4.2 -1.51 1.08-3.25 1.86-5.23 2.34 -1.97 0.48-4.05 0.72-6.24 0.72 -0.73 0-1.63-0.06-2.7-0.19s-2.17-0.32-3.28-0.56c-1.12-0.25-2.17-0.55-3.17-0.91C136 51.44 135.21 51.03 134.6 50.59z"/>
<path d="M193.25 50.98c-2.77 1.66-6.05 2.5-9.84 2.5 -5.13 0-9.28-1.67-12.43-5.01s-4.73-7.67-4.73-12.99c0-5.93 1.7-10.69 5.1-14.29 3.4-3.6 7.93-5.4 13.61-5.4 3.16 0 5.95 0.59 8.37 1.76v5.91c-2.67-1.88-5.53-2.81-8.58-2.81 -3.68 0-6.7 1.32-9.05 3.96s-3.53 6.1-3.53 10.39c0 4.22 1.11 7.55 3.32 9.98s5.19 3.66 8.91 3.66c3.14 0 6.09-1.04 8.86-3.13V50.98z"/>
<path d="M215.56 22.46c-1.01-0.77-2.46-1.16-4.36-1.16 -2.46 0-4.52 1.16-6.17 3.48s-2.48 5.48-2.48 9.49v18.35h-5.77v-36h5.77v7.42h0.14c0.82-2.53 2.07-4.51 3.76-5.92 1.69-1.42 3.57-2.13 5.66-2.13 1.5 0 2.65 0.16 3.45 0.49V22.46z"/>
<path d="M222.18 7.49c-1.03 0-1.91-0.35-2.64-1.05s-1.09-1.59-1.09-2.67c0-1.08 0.36-1.97 1.09-2.69 0.73-0.71 1.61-1.07 2.64-1.07 1.05 0 1.95 0.36 2.69 1.07 0.74 0.72 1.11 1.61 1.11 2.69 0 1.03-0.37 1.91-1.11 2.64C224.13 7.12 223.23 7.49 222.18 7.49zM224.99 52.63h-5.77v-36h5.77V52.63z"/>
<path d="M234.29 47.43h-0.14v21.76h-5.77V16.63h5.77v6.33h0.14c2.84-4.78 6.98-7.17 12.45-7.17 4.64 0 8.26 1.61 10.86 4.83 2.6 3.22 3.9 7.54 3.9 12.96 0 6.02-1.46 10.85-4.39 14.47s-6.94 5.43-12.02 5.43C240.42 53.47 236.82 51.46 234.29 47.43zM234.15 32.91v5.03c0 2.98 0.97 5.5 2.9 7.58s4.39 3.11 7.37 3.11c3.49 0 6.23-1.34 8.21-4.01s2.97-6.39 2.97-11.14c0-4.01-0.93-7.15-2.78-9.42 -1.85-2.27-4.36-3.41-7.52-3.41 -3.35 0-6.05 1.17-8.09 3.5C235.17 26.47 234.15 29.39 234.15 32.91z"/>
<path d="M283.09 52.28c-1.36 0.75-3.15 1.12-5.38 1.12 -6.3 0-9.46-3.52-9.46-10.55v-21.3h-6.19v-4.92h6.19V7.84l5.77-1.86v10.65h9.07v4.92h-9.07v20.28c0 2.41 0.41 4.14 1.23 5.17s2.18 1.55 4.08 1.55c1.45 0 2.71-0.4 3.76-1.2V52.28z"/>
</g>
</svg>
@tailwind base;
@tailwind components;
@tailwind utilities;
/*
.container {
width: 100%;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: radial-gradient(circle, #b3b3b3 10%, transparent 11%), radial-gradient(circle at bottom left, #b3b3b3 5%, transparent 6%), radial-gradient(circle at bottom right, #b3b3b3 5%, transparent 6%), radial-gradient(circle at top left, #b3b3b3 5%, transparent 6%), radial-gradient(circle at top right, #b3b3b3 5%, transparent 6%);
background-size: 1em 1em;
background-color: #ffffff;
}
* {
background-color: white;
}
.list-container {
margin-top: 10px;
} */
\ No newline at end of file
import type { Config } from 'tailwindcss';
const config: Config = {
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}'
],
theme: {
extend: {
colors: {
primary: {
DEFAULT: 'hsl(340, 76%, 47%)',
light: 'hsl(340, 76%, 57%)',
dark: 'hsl(340, 76%, 37%)'
},
secondary: {
DEFAULT: 'hsl(205, 76%, 47%)',
light: 'hsl(205, 76%, 57%)',
dark: 'hsl(205, 76%, 37%)'
},
light: '#f4f4f4',
dark: '#222222'
}
}
},
plugins: []
};
export default config;
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
export const List_data = [
{
id: " 1",
task: "Buy the Groceries",
isCompleted: true
},
{
id: " 2",
task: "Buy the food",
isCompleted: false
},
{
id: "3",
task: "pay the rent",
isCompleted: false
},
{
id: " 4",
task: "savings the money",
isCompleted: true
}
]
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment