Skip to content

Commit

Permalink
Merge pull request #21 from alnavarrop99/fix/form-validate
Browse files Browse the repository at this point in the history
Fix: form validate
  • Loading branch information
alnavarrop99 authored Apr 18, 2024
2 parents cf8fd51 + 74c3511 commit 56f326b
Show file tree
Hide file tree
Showing 19 changed files with 1,044 additions and 600 deletions.
157 changes: 126 additions & 31 deletions src/components/ui/calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,64 +1,159 @@
import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
import { DayPicker } from "react-day-picker"
import * as React from 'react'
import { ChevronLeft, ChevronRight } from 'lucide-react'
import { DayPicker } from 'react-day-picker'

import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"
import { cn } from '@/lib/utils'
import { buttonVariants } from '@/components/ui/button'
import { format, isSameDay } from 'date-fns'
import { HoverCard, HoverCardContent, HoverCardTrigger } from './hover-card'
import clsx from 'clsx'
import { Link } from '@tanstack/react-router'
import { Badge } from './badge'
import { Separator } from '@radix-ui/react-separator'

export type CalendarProps = React.ComponentProps<typeof DayPicker>
/* eslint-disable-next-line */
export type TData = {
type: TType
creditId: number
client: string
cuete: number
}

/* eslint-disable-next-line */
export type TDaysProps = { [date: string]: TData }

export type CalendarProps = React.ComponentProps<typeof DayPicker> & {
days?: TDaysProps
}

type TType = 'mora' | 'warning'

function Calendar({
className,
classNames,
showOutsideDays = true,
days,
...props
}: CalendarProps) {

return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn("p-3", className)}
className={cn('p-3', className)}
classNames={{
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
month: "space-y-4",
caption: "flex justify-center pt-1 relative items-center",
caption_label: "text-sm font-medium",
nav: "space-x-1 flex items-center",
months: 'flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0',
month: 'space-y-4',
caption: 'flex justify-center pt-1 relative items-center',
caption_label: 'text-sm font-medium',
nav: 'space-x-1 flex items-center',
nav_button: cn(
buttonVariants({ variant: "outline" }),
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
buttonVariants({ variant: 'outline' }),
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100'
),
nav_button_previous: "absolute left-1",
nav_button_next: "absolute right-1",
table: "w-full border-collapse space-y-1",
head_row: "flex",
nav_button_previous: 'absolute left-1',
nav_button_next: 'absolute right-1',
table: 'w-full border-collapse space-y-1',
head_row: 'flex',
head_cell:
"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
row: "flex w-full mt-2",
cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
'text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]',
row: 'flex w-full mt-2',
cell: 'h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20',
day: cn(
buttonVariants({ variant: "ghost" }),
"h-9 w-9 p-0 font-normal aria-selected:opacity-100"
buttonVariants({ variant: 'ghost' }),
'h-9 w-9 p-0 font-normal aria-selected:opacity-100'
),
day_range_end: "day-range-end",
day_range_end: 'day-range-end',
day_selected:
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
day_today: "bg-accent text-accent-foreground",
'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground',
day_today: 'bg-accent text-accent-foreground',
day_outside:
"day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
day_disabled: "text-muted-foreground opacity-50",
'day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30',
day_disabled: 'text-muted-foreground opacity-50',
day_range_middle:
"aria-selected:bg-accent aria-selected:text-accent-foreground",
day_hidden: "invisible",
'aria-selected:bg-accent aria-selected:text-accent-foreground',
day_hidden: 'invisible',
...classNames,
}}
components={{
IconLeft: (props) => <ChevronLeft {...props} className="h-4 w-4" />,
IconRight: (props) => <ChevronRight {...props} className="h-4 w-4" />,
Day: !days ? undefined : (({ date }) => (
<HoverDate credit={days?.[format(date, 'dd-MM-yyyy')]} date={date} />
)),
}}
{...props}
/>
)
}
Calendar.displayName = "Calendar"

/* eslint-disable-next-line */
interface THoverDate {
date: Date
credit?: TData
}

/* eslint-disable-next-line */
function HoverDate({ date, credit }: THoverDate) {
if (!credit)
return <span className={clsx("!font-normal", {
"text-foreground": isSameDay( date, new Date() )
})}> {format(date, 'dd')} </span>
return (
<HoverCard>
<HoverCardTrigger
className={clsx('cursor-pointer', {
"font-bold text-destructive after:content-['*']":
credit.type === 'mora',
"font-bold text-primary before:content-['-'] after:content-['-']":
credit.type === 'warning',
})}
>
<Link
className="hover:underline"
to={'/credit/$creditId'}
params={{ creditId: credit?.creditId }}
>
{' '}
{format(date, 'dd')}
</Link>
</HoverCardTrigger>
<HoverCardContent className="w-[15rem] space-y-2 rounded-sm p-2">
<div className="space-x-2 align-middle">
<Link
className="hover:underline"
to={'/credit/$creditId'}
params={{ creditId: credit?.creditId }}
>
{' '}
<b>{text.title({ type: credit.type })}</b>
</Link>
<Badge>{credit.creditId}</Badge>
</div>
<Separator />
<ul className="[&>*]:text-start [&>li]:line-clamp-1">
<li>
{' '}
<b>{text.list.client + ':'}</b> {credit.client}{' '}
</li>
<li>
{' '}
<b>{text.list.ammount + ':'}</b> {credit.cuete}{' '}
</li>
</ul>
</HoverCardContent>
</HoverCard>
)
}

Calendar.displayName = 'Calendar'

export { Calendar }

const text = {
title: ({ type }: { type: TType }) =>
'Credito ' + (type === 'warning' ? 'Pendiente' : 'en Mora'),
list: {
client: 'Cliente',
ammount: 'Numero de cuota',
},
}
27 changes: 21 additions & 6 deletions src/components/ui/loader.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
import clsx from 'clsx'
import * as React from 'react'
import styles from "@/components/ui/loader.module.css"
import styles from '@/components/ui/loader.module.css'

interface TSpinLoader extends React.HTMLAttributes<HTMLSpanElement> {}

const SpinLoader = React.forwardRef< HTMLSpanElement, TSpinLoader>(( { className, ...props }, ref) => (
<span {...props} ref={ref} className={clsx( styles?.["spin-loader"], className )}></span>
))
const SpinLoader = React.forwardRef<HTMLSpanElement, TSpinLoader>(
({ className, ...props }, ref) => (
<span
{...props}
ref={ref}
className={clsx(styles?.['spin-loader'], className)}
></span>
)
)

const BoundleLoader = React.forwardRef<HTMLSpanElement, TSpinLoader>(( { className, ...props }, ref) => (
<span {...props} ref={ref} className={clsx( styles?.["boundle-loader"], className )}></span>
const BoundleLoader = React.forwardRef<
HTMLSpanElement,
React.PropsWithChildren<TSpinLoader>
>(({ className, children, ...props }, ref) => (
<span
{...props}
ref={ref}
className={clsx(styles?.['boundle-loader'], className)}
>
{children}
</span>
))

export { SpinLoader, BoundleLoader }
4 changes: 2 additions & 2 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
--popover-foreground: 210 40% 98%;
--primary: 207 55% 43%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 40 100% 35%;
--secondary-foreground: 40 100% 25%;
--secondary: 40 100% 30%;
--secondary-foreground: 40 85% 20%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 235 26% 67%;
Expand Down
21 changes: 11 additions & 10 deletions src/mocks/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { listStatus } from '@/lib/type/status'
import { listIds } from '@/lib/type/id'
import { listMoraTypes } from '@/lib/type/moraType'
import { listFrecuencys } from '@/lib/type/frecuency'
import { TROLES, listRols } from '@/lib/type/rol'
import { formatISO } from 'date-fns'
import { type TROLES, listRols } from '@/lib/type/rol'
import { add } from 'date-fns'
import { faker } from '@faker-js/faker/locale/en'
import { TPAYMENT_GET_BASE } from '@/api/payment'
import { type TPAYMENT_GET_BASE } from '@/api/payment'

const CLIENTS_LENGTH = 20
const USERS_LENGTH = 10
const USERS_LENGTH = 12
const CREDITS_LENGTH = 20
const REPORTS_LENGTH = 5

Expand Down Expand Up @@ -102,7 +102,7 @@ export const credits = new Map<number, TCREDIT_GET>(
multipleOf: 5.25,
})
const aprobeDate = faker.date.between({
from: new Date('2020-01-01'),
from: new Date('2024'),
to: new Date(),
})
const aditionalDays = faker.number.int(10)
Expand All @@ -120,9 +120,10 @@ export const credits = new Map<number, TCREDIT_GET>(
refDate: aprobeDate,
days: index + 1 + index + 1 * faker.number.int(index + 1),
})
const moraDate = new Date(payDate)
moraDate.setDate(payDate.getDate() + aditionalDays)

const moraDate = add(new Date(payDate), { days: aditionalDays })
const cuoteAmmount = Math.ceil(ammount / cuotesLength)

const payMora = faker.helpers.maybe(
() =>
mora.nombre === 'Valor fijo'
Expand All @@ -140,10 +141,10 @@ export const credits = new Map<number, TCREDIT_GET>(
id: index + 1,
numero_de_cuota: _id,
credito_id: id,
fecha_de_pago: formatISO(payDate),
fecha_de_pago: payDate.toISOString(),
valor_de_cuota: cuoteAmmount,
valor_pagado: pay,
fecha_de_aplicacion_de_mora: formatISO(moraDate),
fecha_de_aplicacion_de_mora: moraDate.toISOString(),
valor_de_mora:
!!payMora && index < paymentsLength ? payMora : 0,
pagada: index <= paymentsLength ? true : false,
Expand Down Expand Up @@ -186,7 +187,7 @@ export const credits = new Map<number, TCREDIT_GET>(
return [
id,
{
fecha_de_aprobacion: formatISO(aprobeDate),
fecha_de_aprobacion: aprobeDate.toISOString(),
id,
owner_id: faker.helpers.arrayElement([...clients?.values()])?.id ?? 1,
monto: ammount,
Expand Down
88 changes: 88 additions & 0 deletions src/pages/-calendar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Badge } from "@/components/ui/badge"
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card"
import { Separator } from "@/components/ui/separator"
import { Link } from "@tanstack/react-router"
import clsx from "clsx"
import { format } from "date-fns"

/* eslint-disable-next-line */
type TType = 'mora' | 'warning'

/* eslint-disable-next-line */
export type TData = {
type: TType
creditId: number
client: string
cuete: number
}

/* eslint-disable-next-line */
export type TDaysProps = { [date: string]: TData }

/* eslint-disable-next-line */
interface THoverDate {
date: Date
credit?: TData
}

/* eslint-disable-next-line */
function HoverDate({ date, credit }: THoverDate) {
if (!credit)
return <span className="!font-normal"> {format(date, 'dd')} </span>
return (
<HoverCard>
<HoverCardTrigger
className={clsx('cursor-pointer', {
"font-bold text-destructive after:content-['*']":
credit.type === 'mora',
"font-bold text-primary before:content-['-'] after:content-['-']":
credit.type === 'warning',
})}
>
<Link
className="hover:underline"
to={'/credit/$creditId'}
params={{ creditId: credit?.creditId }}
>
{' '}
{format(date, 'dd')}
</Link>
</HoverCardTrigger>
<HoverCardContent className="w-[15rem] space-y-2 rounded-sm p-2">
<div className="space-x-2 align-middle">
<Link
className="hover:underline"
to={'/credit/$creditId'}
params={{ creditId: credit?.creditId }}
>
{' '}
<b>{text.title({ type: credit.type })}</b>
</Link>
<Badge>{credit.creditId}</Badge>
</div>
<Separator />
<ul className="[&>*]:text-start [&>li]:line-clamp-1">
<li>
{' '}
<b>{text.list.client + ':'}</b> {credit.client}{' '}
</li>
<li>
{' '}
<b>{text.list.ammount + ':'}</b> {credit.cuete}{' '}
</li>
</ul>
</HoverCardContent>
</HoverCard>
)
}

export { HoverDate }

const text = {
title: ({ type }: { type: TType }) =>
'Credito ' + (type === 'warning' ? 'Pendiente' : 'en Mora'),
list: {
client: 'Cliente',
ammount: 'Numero de cuota',
},
}
Loading

0 comments on commit 56f326b

Please sign in to comment.