use linkify to automatically convert links to href (#15)

This commit is contained in:
Doh
2025-01-03 21:38:36 -05:00
committed by GitHub
parent 140bb9b3e9
commit a4af30bd23
9 changed files with 78 additions and 226 deletions

View File

@@ -1,5 +1,11 @@
# Changelog # Changelog
## Version 0.1.6
### Added
- make links clickable in habit, wishlist and calendar
## Version 0.1.5 ## Version 0.1.5
### Added ### Added

View File

@@ -9,6 +9,7 @@ import { Badge } from '@/components/ui/badge'
import { Progress } from '@/components/ui/progress' import { Progress } from '@/components/ui/progress'
import { WishlistItemType } from '@/lib/types' import { WishlistItemType } from '@/lib/types'
import { Habit } from '@/lib/types' import { Habit } from '@/lib/types'
import Linkify from './linkify'
interface UpcomingItemsProps { interface UpcomingItemsProps {
habits: Habit[] habits: Habit[]
@@ -91,7 +92,9 @@ export default function DailyOverview({
)} )}
</button> </button>
<span className={isCompleted ? 'line-through' : ''}> <span className={isCompleted ? 'line-through' : ''}>
{habit.name} <Linkify>
{habit.name}
</Linkify>
</span> </span>
</span> </span>
<span className="flex items-center text-xs text-muted-foreground"> <span className="flex items-center text-xs text-muted-foreground">
@@ -144,7 +147,11 @@ export default function DailyOverview({
.map((item) => ( .map((item) => (
<div key={item.id} className="bg-secondary/20 p-3 rounded-md"> <div key={item.id} className="bg-secondary/20 p-3 rounded-md">
<div className="flex items-center justify-between mb-2"> <div className="flex items-center justify-between mb-2">
<span className="text-sm">{item.name}</span> <span className="text-sm">
<Linkify>
{item.name}
</Linkify>
</span>
<span className="text-xs flex items-center"> <span className="text-xs flex items-center">
<Coins className="h-3 w-3 text-yellow-400 mr-1" /> <Coins className="h-3 w-3 text-yellow-400 mr-1" />
{item.coinCost} {item.coinCost}

View File

@@ -11,6 +11,7 @@ import { d2s, getNow } from '@/lib/utils'
import { useAtom } from 'jotai' import { useAtom } from 'jotai'
import { settingsAtom } from '@/lib/atoms' import { settingsAtom } from '@/lib/atoms'
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
import Linkify from './linkify'
export default function HabitCalendar() { export default function HabitCalendar() {
const [settings] = useAtom(settingsAtom) const [settings] = useAtom(settingsAtom)
@@ -73,7 +74,9 @@ export default function HabitCalendar() {
const isCompleted = getHabitsForDate(selectedDate.toJSDate()).some(h => h.id === habit.id) const isCompleted = getHabitsForDate(selectedDate.toJSDate()).some(h => h.id === habit.id)
return ( return (
<li key={habit.id} className="flex items-center justify-between"> <li key={habit.id} className="flex items-center justify-between">
<span>{habit.name}</span> <span>
<Linkify>{habit.name}</Linkify>
</span>
{isCompleted ? ( {isCompleted ? (
<Badge variant="default">Completed</Badge> <Badge variant="default">Completed</Badge>
) : ( ) : (

View File

@@ -1,4 +1,5 @@
import Header from './Header' import Header from './Header'
import LinkifyComponent from './linkify'
import Navigation from './Navigation' import Navigation from './Navigation'
export default function Layout({ children }: { children: React.ReactNode }) { export default function Layout({ children }: { children: React.ReactNode }) {

View File

@@ -1,40 +0,0 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Progress } from '@/components/ui/progress'
// This would typically come from your backend or state management
const rewards = [
{ id: '1', name: 'Day off work', coinCost: 500 },
{ id: '2', name: 'Movie night', coinCost: 100 },
{ id: '3', name: 'New book', coinCost: 50 },
]
interface RewardProgressProps {
coinBalance: number
}
export default function RewardProgress({ coinBalance }: RewardProgressProps) {
return (
<Card>
<CardHeader>
<CardTitle>Progress Towards Rewards</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-4">
{rewards.map((reward) => {
const progress = Math.min((coinBalance / reward.coinCost) * 100, 100)
return (
<div key={reward.id}>
<div className="flex justify-between mb-1">
<span className="text-sm font-medium">{reward.name}</span>
<span className="text-sm font-medium">{coinBalance}/{reward.coinCost} coins</span>
</div>
<Progress value={progress} className="w-full" />
</div>
)
})}
</div>
</CardContent>
</Card>
)
}

5
components/linkify.tsx Normal file
View File

@@ -0,0 +1,5 @@
import Linkify0 from "linkify-react";
export default function Linkify({ children }: { children: React.ReactNode }) {
return <Linkify0 options={{ className: "underline" }}>{children}</Linkify0>;
}

View File

@@ -1,6 +1,7 @@
import * as React from "react" import * as React from "react"
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils"
import Linkify from "../linkify"
const Card = React.forwardRef< const Card = React.forwardRef<
HTMLDivElement, HTMLDivElement,
@@ -33,11 +34,13 @@ const CardTitle = React.forwardRef<
HTMLDivElement, HTMLDivElement,
React.HTMLAttributes<HTMLDivElement> React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => ( >(({ className, ...props }, ref) => (
<div <Linkify>
ref={ref} <div
className={cn("font-semibold leading-none tracking-tight", className)} ref={ref}
{...props} className={cn("font-semibold leading-none tracking-tight", className)}
/> {...props}
/>
</Linkify>
)) ))
CardTitle.displayName = "CardTitle" CardTitle.displayName = "CardTitle"
@@ -45,11 +48,13 @@ const CardDescription = React.forwardRef<
HTMLDivElement, HTMLDivElement,
React.HTMLAttributes<HTMLDivElement> React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => ( >(({ className, ...props }, ref) => (
<div <Linkify>
ref={ref} <div
className={cn("text-sm text-muted-foreground", className)} ref={ref}
{...props} className={cn("text-sm text-muted-foreground", className)}
/> {...props}
/>
</Linkify>
)) ))
CardDescription.displayName = "CardDescription" CardDescription.displayName = "CardDescription"

205
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "habittrove", "name": "habittrove",
"version": "0.1.4", "version": "0.1.5",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "habittrove", "name": "habittrove",
"version": "0.1.4", "version": "0.1.5",
"dependencies": { "dependencies": {
"@next/font": "^14.2.15", "@next/font": "^14.2.15",
"@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-dialog": "^1.1.4",
@@ -16,16 +16,16 @@
"@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-switch": "^1.1.2", "@radix-ui/react-switch": "^1.1.2",
"@radix-ui/react-toast": "^1.2.4", "@radix-ui/react-toast": "^1.2.4",
"@types/bun": "^1.1.14",
"@types/canvas-confetti": "^1.9.0", "@types/canvas-confetti": "^1.9.0",
"@uiw/react-heat-map": "^2.3.2", "@uiw/react-heat-map": "^2.3.2",
"bun": "^1.1.42",
"canvas-confetti": "^1.9.3", "canvas-confetti": "^1.9.3",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"jotai": "^2.8.0", "jotai": "^2.8.0",
"js-confetti": "^0.12.0", "js-confetti": "^0.12.0",
"linkify": "^0.2.1",
"linkify-react": "^4.2.0",
"lucide-react": "^0.469.0", "lucide-react": "^0.469.0",
"luxon": "^3.5.0", "luxon": "^3.5.0",
"next": "15.1.3", "next": "15.1.3",
@@ -41,6 +41,7 @@
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3", "@eslint/eslintrc": "^3",
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.15",
"@types/bun": "^1.1.14",
"@types/luxon": "^3.4.2", "@types/luxon": "^3.4.2",
"@types/node": "^20.17.10", "@types/node": "^20.17.10",
"@types/react": "^19", "@types/react": "^19",
@@ -893,138 +894,6 @@
"node": ">=12.4.0" "node": ">=12.4.0"
} }
}, },
"node_modules/@oven/bun-darwin-aarch64": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.1.42.tgz",
"integrity": "sha512-7kQkTVr99ndcU72xlIzA2QLavvT/DnEhvwTAq7LKi9/P3GtSAkhoA6UWZUa7pYw7OYHpUrEGXlV+PR3LllkGnw==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@oven/bun-darwin-x64": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.1.42.tgz",
"integrity": "sha512-2IPJnLvwLlD8YaXPbWwlpw2UvVrZE6/0uRbcSJNzZQAAZjEfN8AodqNRhggptn0A9vDmAw6q1U07QbiE4ilofw==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@oven/bun-darwin-x64-baseline": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.1.42.tgz",
"integrity": "sha512-26mtzVRLp/x89s27fXExG1vCCBOOFHLdqVYg/lHZMdDNHSh7Q7UiUhDRa+aVBlbsaGfw1LzoXdhh7Zy2hlF/6w==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@oven/bun-linux-aarch64": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.1.42.tgz",
"integrity": "sha512-qkoqI+oMcQ8GUej71qkAVj/VLlVpoBRyiYBQYq4yWsy+FU2jr2KWTeNZWrsY2crDiZj38AMNXJiKBr/EMy4MRg==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
]
},
"node_modules/@oven/bun-linux-aarch64-musl": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64-musl/-/bun-linux-aarch64-musl-1.1.42.tgz",
"integrity": "sha512-PwbNLoirazjTYTSydn2AnId0jBJexZ99cwftOfdzIGCF5anEWvNEZ8PL4o79jHIhE0t01qGc8br9fQbiQ+iArw==",
"cpu": [
"aarch64"
],
"optional": true,
"os": [
"linux"
]
},
"node_modules/@oven/bun-linux-x64": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.1.42.tgz",
"integrity": "sha512-rV8Eqnvo/1z0nwYSiLrbl0F4G8uFQxlGA4P0zggW9W4PSiSHSRhG1aazG/8esBLzJI9CdFNncrtmiRTmWl1mIg==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
]
},
"node_modules/@oven/bun-linux-x64-baseline": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.1.42.tgz",
"integrity": "sha512-UzRNXgHEARFECgz30eot23OnPzd0J2L5SEsGhnGRhfJ706kjz0XmuGMnb9nmnoyHBcd2iSjk4nci1BlGmu4wCA==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
]
},
"node_modules/@oven/bun-linux-x64-musl": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl/-/bun-linux-x64-musl-1.1.42.tgz",
"integrity": "sha512-Djye8lPlhVNXdGbMF4bShVop8qvqPhPuPrhxEHfYJ8qhudSs2MiOWR5stvBWe8KLKahqDAWfWXuxByAXVhqb2Q==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
]
},
"node_modules/@oven/bun-linux-x64-musl-baseline": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl-baseline/-/bun-linux-x64-musl-baseline-1.1.42.tgz",
"integrity": "sha512-zgeiYJRGO3K4uK6Qdj1B5ZbU9NJxLwF9YGDFu9MtqEplyGNq7SpeuamvcP6SlZGgrVnc3AWrHFEYrVlv5Lqt+w==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
]
},
"node_modules/@oven/bun-windows-x64": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.1.42.tgz",
"integrity": "sha512-6eyHs6fVRCy0ujltYTwSX3bug+PqlgZRBv8x0PPekviaCJWYrFKVpHodA2972+Mih2pATurBSX2sLVq5uJUU7Q==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"win32"
]
},
"node_modules/@oven/bun-windows-x64-baseline": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.1.42.tgz",
"integrity": "sha512-xnlYa1jKknImCw7xmSD91H8e+w3BC6mIShOfHhFWfNhdyvEtundXhIu7VddwxKBMs5S/iiFJiutnZ2EyLq4CAQ==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"win32"
]
},
"node_modules/@pkgjs/parseargs": { "node_modules/@pkgjs/parseargs": {
"version": "0.11.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -1707,6 +1576,7 @@
"version": "1.1.14", "version": "1.1.14",
"resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.1.14.tgz", "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.1.14.tgz",
"integrity": "sha512-opVYiFGtO2af0dnWBdZWlioLBoxSdDO5qokaazLhq8XQtGZbY4pY3/JxY8Zdf/hEwGubbp7ErZXoN1+h2yesxA==", "integrity": "sha512-opVYiFGtO2af0dnWBdZWlioLBoxSdDO5qokaazLhq8XQtGZbY4pY3/JxY8Zdf/hEwGubbp7ErZXoN1+h2yesxA==",
"dev": true,
"dependencies": { "dependencies": {
"bun-types": "1.1.37" "bun-types": "1.1.37"
} }
@@ -1856,6 +1726,7 @@
"version": "20.17.10", "version": "20.17.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz",
"integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==",
"dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
} }
@@ -1886,6 +1757,7 @@
"version": "8.5.13", "version": "8.5.13",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz",
"integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==",
"dev": true,
"dependencies": { "dependencies": {
"@types/node": "*" "@types/node": "*"
} }
@@ -2751,43 +2623,11 @@
"dev": true, "dev": true,
"peer": true "peer": true
}, },
"node_modules/bun": {
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/bun/-/bun-1.1.42.tgz",
"integrity": "sha512-PckeNolMEBaBEzixTMvp0jJD9r/9lly8AfctILi1ve14zwwChFjsxI4TJLQO2yezzOjVeG0u7xf8WQFbS7GjAA==",
"cpu": [
"arm64",
"x64",
"aarch64"
],
"hasInstallScript": true,
"os": [
"darwin",
"linux",
"win32"
],
"bin": {
"bun": "bin/bun.exe",
"bunx": "bin/bun.exe"
},
"optionalDependencies": {
"@oven/bun-darwin-aarch64": "1.1.42",
"@oven/bun-darwin-x64": "1.1.42",
"@oven/bun-darwin-x64-baseline": "1.1.42",
"@oven/bun-linux-aarch64": "1.1.42",
"@oven/bun-linux-aarch64-musl": "1.1.42",
"@oven/bun-linux-x64": "1.1.42",
"@oven/bun-linux-x64-baseline": "1.1.42",
"@oven/bun-linux-x64-musl": "1.1.42",
"@oven/bun-linux-x64-musl-baseline": "1.1.42",
"@oven/bun-windows-x64": "1.1.42",
"@oven/bun-windows-x64-baseline": "1.1.42"
}
},
"node_modules/bun-types": { "node_modules/bun-types": {
"version": "1.1.37", "version": "1.1.37",
"resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.1.37.tgz", "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.1.37.tgz",
"integrity": "sha512-C65lv6eBr3LPJWFZ2gswyrGZ82ljnH8flVE03xeXxKhi2ZGtFiO4isRKTKnitbSqtRAcaqYSR6djt1whI66AbA==", "integrity": "sha512-C65lv6eBr3LPJWFZ2gswyrGZ82ljnH8flVE03xeXxKhi2ZGtFiO4isRKTKnitbSqtRAcaqYSR6djt1whI66AbA==",
"dev": true,
"dependencies": { "dependencies": {
"@types/node": "~20.12.8", "@types/node": "~20.12.8",
"@types/ws": "~8.5.10" "@types/ws": "~8.5.10"
@@ -2797,6 +2637,7 @@
"version": "20.12.14", "version": "20.12.14",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.14.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.14.tgz",
"integrity": "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==", "integrity": "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==",
"dev": true,
"dependencies": { "dependencies": {
"undici-types": "~5.26.4" "undici-types": "~5.26.4"
} }
@@ -2804,7 +2645,8 @@
"node_modules/bun-types/node_modules/undici-types": { "node_modules/bun-types/node_modules/undici-types": {
"version": "5.26.5", "version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true
}, },
"node_modules/busboy": { "node_modules/busboy": {
"version": "1.6.0", "version": "1.6.0",
@@ -5385,6 +5227,26 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
}, },
"node_modules/linkify": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/linkify/-/linkify-0.2.1.tgz",
"integrity": "sha512-Esq4rfRRHmH3RTqAsnGq33MwE0HqyeNWHpNbWFsV8jEnuPKseiOPjzWvK2i3REqwZpnbCxTh1yxAKzceKKFDGQ=="
},
"node_modules/linkify-react": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/linkify-react/-/linkify-react-4.2.0.tgz",
"integrity": "sha512-dIcDGo+n4FP2FPIHDcqB7cUE+omkcEgQJpc7sNNP4+XZ9FUhFAkKjGnHMzsZM+B4yF93sK166z9K5cKTe/JpzA==",
"peerDependencies": {
"linkifyjs": "^4.0.0",
"react": ">= 15.0.0"
}
},
"node_modules/linkifyjs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.2.0.tgz",
"integrity": "sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw==",
"peer": true
},
"node_modules/loader-runner": { "node_modules/loader-runner": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
@@ -8238,7 +8100,8 @@
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "6.19.8", "version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"dev": true
}, },
"node_modules/unified": { "node_modules/unified": {
"version": "11.0.5", "version": "11.0.5",

View File

@@ -1,6 +1,6 @@
{ {
"name": "habittrove", "name": "habittrove",
"version": "0.1.5", "version": "0.1.6",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev --turbopack", "dev": "next dev --turbopack",
@@ -27,6 +27,8 @@
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"jotai": "^2.8.0", "jotai": "^2.8.0",
"js-confetti": "^0.12.0", "js-confetti": "^0.12.0",
"linkify": "^0.2.1",
"linkify-react": "^4.2.0",
"lucide-react": "^0.469.0", "lucide-react": "^0.469.0",
"luxon": "^3.5.0", "luxon": "^3.5.0",
"next": "15.1.3", "next": "15.1.3",
@@ -42,11 +44,11 @@
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3", "@eslint/eslintrc": "^3",
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.15",
"@types/bun": "^1.1.14",
"@types/luxon": "^3.4.2", "@types/luxon": "^3.4.2",
"@types/node": "^20.17.10", "@types/node": "^20.17.10",
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19", "@types/react-dom": "^19",
"@types/bun": "^1.1.14",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "15.1.3", "eslint-config-next": "15.1.3",
"eslint-plugin-unused-imports": "^4.1.4", "eslint-plugin-unused-imports": "^4.1.4",