mirror of
https://github.com/ManInDark/HabitTrove.git
synced 2026-01-21 06:34:30 +01:00
fix: resolved linting problems
This commit is contained in:
@@ -1,36 +1,32 @@
|
|||||||
'use server'
|
'use server'
|
||||||
|
|
||||||
import fs from 'fs/promises'
|
import { getCurrentUser, saltAndHashPassword, verifyPassword } from "@/lib/server-helpers";
|
||||||
import path from 'path'
|
|
||||||
import {
|
import {
|
||||||
HabitsData,
|
|
||||||
CoinsData,
|
CoinsData,
|
||||||
CoinTransaction,
|
CoinTransaction,
|
||||||
TransactionType,
|
|
||||||
WishlistItemType,
|
|
||||||
WishlistData,
|
|
||||||
Settings,
|
|
||||||
DataType,
|
|
||||||
DATA_DEFAULTS,
|
DATA_DEFAULTS,
|
||||||
getDefaultSettings,
|
DataType,
|
||||||
UserData,
|
|
||||||
getDefaultUsersData,
|
|
||||||
User,
|
|
||||||
getDefaultWishlistData,
|
|
||||||
getDefaultHabitsData,
|
|
||||||
getDefaultCoinsData,
|
getDefaultCoinsData,
|
||||||
|
getDefaultHabitsData,
|
||||||
|
getDefaultSettings,
|
||||||
|
getDefaultUsersData,
|
||||||
|
getDefaultWishlistData,
|
||||||
|
HabitsData,
|
||||||
Permission,
|
Permission,
|
||||||
ServerSettings
|
ServerSettings,
|
||||||
} from '@/lib/types'
|
Settings,
|
||||||
import { d2t, deepMerge, getNow, checkPermission, uuid } from '@/lib/utils';
|
TransactionType,
|
||||||
import { verifyPassword } from "@/lib/server-helpers";
|
User,
|
||||||
import { saltAndHashPassword } from "@/lib/server-helpers";
|
UserData,
|
||||||
|
WishlistData,
|
||||||
|
WishlistItemType
|
||||||
|
} from '@/lib/types';
|
||||||
|
import { d2t, getNow, uuid } from '@/lib/utils';
|
||||||
import { signInSchema } from '@/lib/zod';
|
import { signInSchema } from '@/lib/zod';
|
||||||
import { auth } from '@/auth';
|
import fs from 'fs/promises';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { getCurrentUser, getCurrentUserId } from '@/lib/server-helpers'
|
import path from 'path';
|
||||||
|
|
||||||
import { PermissionError } from '@/lib/exceptions'
|
|
||||||
|
|
||||||
type ResourceType = 'habit' | 'wishlist' | 'coins'
|
type ResourceType = 'habit' | 'wishlist' | 'coins'
|
||||||
type ActionType = 'write' | 'interact'
|
type ActionType = 'write' | 'interact'
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import Layout from '@/components/Layout'
|
|
||||||
import HabitCalendar from '@/components/HabitCalendar'
|
import HabitCalendar from '@/components/HabitCalendar'
|
||||||
import { ViewToggle } from '@/components/ViewToggle'
|
|
||||||
import CompletionCountBadge from '@/components/CompletionCountBadge'
|
|
||||||
|
|
||||||
export default function CalendarPage() {
|
export default function CalendarPage() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import Layout from '@/components/Layout'
|
|
||||||
import CoinsManager from '@/components/CoinsManager'
|
import CoinsManager from '@/components/CoinsManager'
|
||||||
|
|
||||||
export default function CoinsPage() {
|
export default function CoinsPage() {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useHabits } from "@/hooks/useHabits";
|
|
||||||
import { habitsAtom, settingsAtom } from "@/lib/atoms";
|
import { habitsAtom, settingsAtom } from "@/lib/atoms";
|
||||||
import { Habit } from "@/lib/types";
|
import { Habit } from "@/lib/types";
|
||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import Layout from '@/components/Layout'
|
|
||||||
import HabitList from '@/components/HabitList'
|
import HabitList from '@/components/HabitList'
|
||||||
import { ViewToggle } from '@/components/ViewToggle'
|
|
||||||
|
|
||||||
export default function HabitsPage() {
|
export default function HabitsPage() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import './globals.css'
|
|
||||||
import { Inter } from 'next/font/google'
|
|
||||||
import { DM_Sans } from 'next/font/google'
|
|
||||||
import { JotaiProvider } from '@/components/jotai-providers'
|
|
||||||
import { Suspense } from 'react'
|
|
||||||
import { JotaiHydrate } from '@/components/jotai-hydrate'
|
import { JotaiHydrate } from '@/components/jotai-hydrate'
|
||||||
import { loadSettings, loadHabitsData, loadCoinsData, loadWishlistData, loadUsersData, loadServerSettings } from './actions/data'
|
import { JotaiProvider } from '@/components/jotai-providers'
|
||||||
import Layout from '@/components/Layout'
|
import Layout from '@/components/Layout'
|
||||||
import { Toaster } from '@/components/ui/toaster'
|
|
||||||
import { ThemeProvider } from "@/components/theme-provider"
|
import { ThemeProvider } from "@/components/theme-provider"
|
||||||
|
import { Toaster } from '@/components/ui/toaster'
|
||||||
import { SessionProvider } from 'next-auth/react'
|
import { SessionProvider } from 'next-auth/react'
|
||||||
|
import { DM_Sans } from 'next/font/google'
|
||||||
|
import { Suspense } from 'react'
|
||||||
|
import { loadCoinsData, loadHabitsData, loadServerSettings, loadSettings, loadUsersData, loadWishlistData } from './actions/data'
|
||||||
|
import './globals.css'
|
||||||
|
|
||||||
|
|
||||||
// Inter (clean, modern, excellent readability)
|
// Inter (clean, modern, excellent readability)
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
import { DynamicTimeNoSSR } from '@/components/DynamicTimeNoSSR';
|
||||||
import { Switch } from '@/components/ui/switch';
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import { Label } from '@/components/ui/label';
|
import { Label } from '@/components/ui/label';
|
||||||
|
import { Switch } from '@/components/ui/switch';
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from "@/components/ui/tooltip";
|
} from "@/components/ui/tooltip";
|
||||||
import { DynamicTimeNoSSR } from '@/components/DynamicTimeNoSSR';
|
|
||||||
import { useAtom } from 'jotai';
|
|
||||||
import { settingsAtom } from '@/lib/atoms';
|
import { settingsAtom } from '@/lib/atoms';
|
||||||
import { Settings, WeekDay } from '@/lib/types'
|
import { Settings, WeekDay } from '@/lib/types';
|
||||||
import { saveSettings, uploadAvatar } from '../actions/data'
|
import { useAtom } from 'jotai';
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
import { Info } from 'lucide-react'; // Import Info icon
|
||||||
import { Button } from '@/components/ui/button';
|
import { saveSettings } from '../actions/data';
|
||||||
import { User, Info } from 'lucide-react'; // Import Info icon
|
|
||||||
|
|
||||||
export default function SettingsPage() {
|
export default function SettingsPage() {
|
||||||
const [settings, setSettings] = useAtom(settingsAtom);
|
const [settings, setSettings] = useAtom(settingsAtom);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import Layout from '@/components/Layout'
|
|
||||||
import WishlistManager from '@/components/WishlistManager'
|
import WishlistManager from '@/components/WishlistManager'
|
||||||
|
|
||||||
export default function WishlistPage() {
|
export default function WishlistPage() {
|
||||||
|
|||||||
@@ -1,33 +1,24 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState } from 'react'
|
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
||||||
import { RRule, RRuleSet, rrulestr } from 'rrule'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { settingsAtom, browserSettingsAtom, usersAtom } from '@/lib/atoms'
|
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'
|
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||||
import { Switch } from '@/components/ui/switch'
|
|
||||||
import { Input } from '@/components/ui/input'
|
import { Input } from '@/components/ui/input'
|
||||||
import { Label } from '@/components/ui/label'
|
import { Label } from '@/components/ui/label'
|
||||||
import { Textarea } from '@/components/ui/textarea'
|
|
||||||
import { Info, SmilePlus, Zap } from 'lucide-react'
|
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||||
|
import { Textarea } from '@/components/ui/textarea'
|
||||||
|
import { settingsAtom, usersAtom } from '@/lib/atoms'
|
||||||
|
import { useHelpers } from '@/lib/client-helpers'
|
||||||
|
import { INITIAL_DUE, INITIAL_RECURRENCE_RULE, QUICK_DATES } from '@/lib/constants'
|
||||||
|
import { Habit } from '@/lib/types'
|
||||||
|
import { convertHumanReadableFrequencyToMachineReadable, convertMachineReadableFrequencyToHumanReadable, d2t, serializeRRule } from '@/lib/utils'
|
||||||
import data from '@emoji-mart/data'
|
import data from '@emoji-mart/data'
|
||||||
import Picker from '@emoji-mart/react'
|
import Picker from '@emoji-mart/react'
|
||||||
import { Habit, SafeUser } from '@/lib/types'
|
import { useAtom } from 'jotai'
|
||||||
import { convertHumanReadableFrequencyToMachineReadable, convertMachineReadableFrequencyToHumanReadable, d2s, d2t, serializeRRule } from '@/lib/utils'
|
import { SmilePlus, Zap } from 'lucide-react'
|
||||||
import { INITIAL_DUE, INITIAL_RECURRENCE_RULE, QUICK_DATES, RECURRENCE_RULE_MAP } from '@/lib/constants'
|
|
||||||
import * as chrono from 'chrono-node';
|
|
||||||
import { DateTime } from 'luxon'
|
import { DateTime } from 'luxon'
|
||||||
import {
|
import { useState } from 'react'
|
||||||
Select,
|
import { RRule } from 'rrule'
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/components/ui/select"
|
|
||||||
import { useHelpers } from '@/lib/client-helpers'
|
|
||||||
|
|
||||||
interface AddEditHabitModalProps {
|
interface AddEditHabitModalProps {
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
import { useState, useEffect } from 'react'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { usersAtom } from '@/lib/atoms'
|
|
||||||
import { useHelpers } from '@/lib/client-helpers'
|
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar'
|
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||||
import { Input } from '@/components/ui/input'
|
import { Input } from '@/components/ui/input'
|
||||||
import { Label } from '@/components/ui/label'
|
import { Label } from '@/components/ui/label'
|
||||||
import { Textarea } from '@/components/ui/textarea'
|
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
import { Textarea } from '@/components/ui/textarea'
|
||||||
import { SmilePlus, Info } from 'lucide-react'
|
import { usersAtom } from '@/lib/atoms'
|
||||||
|
import { useHelpers } from '@/lib/client-helpers'
|
||||||
|
import { WishlistItemType } from '@/lib/types'
|
||||||
import data from '@emoji-mart/data'
|
import data from '@emoji-mart/data'
|
||||||
import Picker from '@emoji-mart/react'
|
import Picker from '@emoji-mart/react'
|
||||||
import { WishlistItemType } from '@/lib/types'
|
import { useAtom } from 'jotai'
|
||||||
|
import { SmilePlus } from 'lucide-react'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar'
|
||||||
|
|
||||||
interface AddEditWishlistItemModalProps {
|
interface AddEditWishlistItemModalProps {
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default function ClientWrapper({ children }: { children: ReactNode }) {
|
|||||||
if (!currentUserId && !userSelect) {
|
if (!currentUserId && !userSelect) {
|
||||||
setUserSelect(true)
|
setUserSelect(true)
|
||||||
}
|
}
|
||||||
}, [currentUserId, status, userSelect])
|
}, [currentUserId, status, userSelect, setUserSelect])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState, useEffect, useRef } from 'react' // Import useEffect, useRef
|
|
||||||
import { useSearchParams } from 'next/navigation' // Import useSearchParams
|
|
||||||
import { t2d, d2s, getNow, isSameDate } from '@/lib/utils'
|
|
||||||
import { Button } from '@/components/ui/button'
|
|
||||||
import { FormattedNumber } from '@/components/FormattedNumber'
|
import { FormattedNumber } from '@/components/FormattedNumber'
|
||||||
import { History, Pencil } from 'lucide-react'
|
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
||||||
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'
|
import { Button } from '@/components/ui/button'
|
||||||
import EmptyState from './EmptyState'
|
|
||||||
import { Input } from '@/components/ui/input'
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||||
import { settingsAtom, usersAtom } from '@/lib/atoms'
|
import { Input } from '@/components/ui/input'
|
||||||
import Link from 'next/link'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { useCoins } from '@/hooks/useCoins'
|
import { useCoins } from '@/hooks/useCoins'
|
||||||
import { TransactionNoteEditor } from './TransactionNoteEditor'
|
import { settingsAtom, usersAtom } from '@/lib/atoms'
|
||||||
import { useHelpers } from '@/lib/client-helpers'
|
import { useHelpers } from '@/lib/client-helpers'
|
||||||
|
import { d2s, t2d } from '@/lib/utils'
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
|
import { History } from 'lucide-react'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { useSearchParams } from 'next/navigation'; // Import useSearchParams
|
||||||
|
import { useEffect, useRef, useState } from 'react'; // Import useEffect, useRef
|
||||||
|
import EmptyState from './EmptyState'
|
||||||
|
import { TransactionNoteEditor } from './TransactionNoteEditor'
|
||||||
|
|
||||||
export default function CoinsManager() {
|
export default function CoinsManager() {
|
||||||
const { currentUser } = useHelpers()
|
const { currentUser } = useHelpers()
|
||||||
@@ -53,7 +53,7 @@ export default function CoinsManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Only run when userIdFromQuery or currentUser changes, avoid re-running on selectedUser change within this effect
|
// Only run when userIdFromQuery or currentUser changes, avoid re-running on selectedUser change within this effect
|
||||||
}, [userIdFromQuery, currentUser, usersData.users]);
|
}, [userIdFromQuery, currentUser, usersData.users, selectedUser]);
|
||||||
|
|
||||||
// Effect to scroll to highlighted transaction
|
// Effect to scroll to highlighted transaction
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { Badge } from "@/components/ui/badge"
|
import { Badge } from "@/components/ui/badge"
|
||||||
import { useAtom } from 'jotai'
|
import { completedHabitsMapAtom, habitsByDateFamily, settingsAtom } from '@/lib/atoms'
|
||||||
import { completedHabitsMapAtom, habitsAtom, habitsByDateFamily } from '@/lib/atoms'
|
|
||||||
import { getTodayInTimezone } from '@/lib/utils'
|
import { getTodayInTimezone } from '@/lib/utils'
|
||||||
import { useHabits } from '@/hooks/useHabits'
|
import { useAtom } from 'jotai'
|
||||||
import { settingsAtom } from '@/lib/atoms'
|
|
||||||
|
|
||||||
interface CompletionCountBadgeProps {
|
interface CompletionCountBadgeProps {
|
||||||
type: 'habits' | 'tasks'
|
type: 'habits' | 'tasks'
|
||||||
|
|||||||
@@ -1,35 +1,31 @@
|
|||||||
import { Circle, Coins, ArrowRight, CircleCheck, ChevronDown, ChevronUp, Plus, Pin, AlertTriangle } from 'lucide-react' // Removed unused icons
|
import { Badge } from '@/components/ui/badge'
|
||||||
import CompletionCountBadge from './CompletionCountBadge'
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||||
import {
|
import {
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
ContextMenuContent,
|
ContextMenuContent,
|
||||||
ContextMenuItem,
|
ContextMenuTrigger
|
||||||
ContextMenuSeparator,
|
|
||||||
ContextMenuTrigger,
|
|
||||||
} from "@/components/ui/context-menu"
|
} from "@/components/ui/context-menu"
|
||||||
import { cn } from '@/lib/utils'
|
import { Progress } from '@/components/ui/progress'
|
||||||
import Link from 'next/link'
|
|
||||||
import { useState } from 'react'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { pomodoroAtom, settingsAtom, completedHabitsMapAtom, browserSettingsAtom, BrowserSettings, hasTasksAtom } from '@/lib/atoms'
|
|
||||||
import { getTodayInTimezone, isSameDate, t2d, d2t, getNow, isHabitDue, isTaskOverdue } from '@/lib/utils'
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
|
||||||
import { Badge } from '@/components/ui/badge'
|
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from "@/components/ui/tooltip"
|
} from "@/components/ui/tooltip"
|
||||||
import { Progress } from '@/components/ui/progress'
|
|
||||||
import { Settings, WishlistItemType } from '@/lib/types'
|
|
||||||
import { Habit } from '@/lib/types'
|
|
||||||
import Linkify from './linkify'
|
|
||||||
import { useHabits } from '@/hooks/useHabits'
|
import { useHabits } from '@/hooks/useHabits'
|
||||||
|
import { browserSettingsAtom, completedHabitsMapAtom, hasTasksAtom, pomodoroAtom, settingsAtom } from '@/lib/atoms'
|
||||||
|
import { Habit, WishlistItemType } from '@/lib/types'
|
||||||
|
import { cn, d2t, getNow, getTodayInTimezone, isHabitDue, isSameDate, isTaskOverdue, t2d } from '@/lib/utils'
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
|
import { AlertTriangle, ArrowRight, ChevronDown, ChevronUp, Circle, CircleCheck, Coins, Pin, Plus } from 'lucide-react'; // Removed unused icons
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { useState } from 'react'
|
||||||
import AddEditHabitModal from './AddEditHabitModal'
|
import AddEditHabitModal from './AddEditHabitModal'
|
||||||
|
import CompletionCountBadge from './CompletionCountBadge'
|
||||||
import ConfirmDialog from './ConfirmDialog'
|
import ConfirmDialog from './ConfirmDialog'
|
||||||
import { Button } from './ui/button'
|
|
||||||
import { HabitContextMenuItems } from './HabitContextMenuItems'
|
import { HabitContextMenuItems } from './HabitContextMenuItems'
|
||||||
|
import Linkify from './linkify'
|
||||||
|
import { Button } from './ui/button'
|
||||||
|
|
||||||
interface UpcomingItemsProps {
|
interface UpcomingItemsProps {
|
||||||
habits: Habit[]
|
habits: Habit[]
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import { useCoins } from '@/hooks/useCoins'
|
||||||
|
import { habitsAtom, wishlistAtom } from '@/lib/atoms'
|
||||||
import { useAtom } from 'jotai'
|
import { useAtom } from 'jotai'
|
||||||
import { wishlistAtom, habitsAtom, settingsAtom } from '@/lib/atoms'
|
import CoinBalance from './CoinBalance'
|
||||||
import DailyOverview from './DailyOverview'
|
import DailyOverview from './DailyOverview'
|
||||||
import HabitStreak from './HabitStreak'
|
import HabitStreak from './HabitStreak'
|
||||||
import CoinBalance from './CoinBalance'
|
|
||||||
import { useHabits } from '@/hooks/useHabits'
|
|
||||||
import { useCoins } from '@/hooks/useCoins'
|
|
||||||
|
|
||||||
export default function Dashboard() {
|
export default function Dashboard() {
|
||||||
const [habitsData] = useAtom(habitsAtom)
|
const [habitsData] = useAtom(habitsAtom)
|
||||||
const habits = habitsData.habits
|
const habits = habitsData.habits
|
||||||
const [settings] = useAtom(settingsAtom)
|
|
||||||
const { balance } = useCoins()
|
const { balance } = useCoins()
|
||||||
const [wishlist] = useAtom(wishlistAtom)
|
const [wishlist] = useAtom(wishlistAtom)
|
||||||
const wishlistItems = wishlist.items
|
const wishlistItems = wishlist.items
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState, useMemo, useCallback } from 'react'
|
import CompletionCountBadge from '@/components/CompletionCountBadge'
|
||||||
import { Calendar } from '@/components/ui/calendar'
|
import { Calendar } from '@/components/ui/calendar'
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||||
import CompletionCountBadge from '@/components/CompletionCountBadge'
|
|
||||||
import { Button } from '@/components/ui/button'
|
|
||||||
import { Check, Circle, CircleCheck } from 'lucide-react'
|
|
||||||
import { d2s, getNow, t2d, getCompletedHabitsForDate, isHabitDue, getISODate, getCompletionsForToday, getCompletionsForDate } from '@/lib/utils'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { useHabits } from '@/hooks/useHabits'
|
import { useHabits } from '@/hooks/useHabits'
|
||||||
import { habitsAtom, settingsAtom, completedHabitsMapAtom, hasTasksAtom } from '@/lib/atoms'
|
import { completedHabitsMapAtom, habitsAtom, hasTasksAtom, settingsAtom } from '@/lib/atoms'
|
||||||
import { DateTime } from 'luxon'
|
|
||||||
import Linkify from './linkify'
|
|
||||||
import { Habit } from '@/lib/types'
|
import { Habit } from '@/lib/types'
|
||||||
|
import { d2s, getCompletionsForDate, getISODate, getNow, isHabitDue } from '@/lib/utils'
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
|
import { Circle, CircleCheck } from 'lucide-react'
|
||||||
|
import { DateTime } from 'luxon'
|
||||||
|
import { useCallback, useMemo, useState } from 'react'
|
||||||
|
import Linkify from './linkify'
|
||||||
|
|
||||||
export default function HabitCalendar() {
|
export default function HabitCalendar() {
|
||||||
const { completePastHabit } = useHabits()
|
const { completePastHabit } = useHabits()
|
||||||
|
|||||||
@@ -1,24 +1,20 @@
|
|||||||
import { Habit, SafeUser, User, Permission } from '@/lib/types'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { settingsAtom, pomodoroAtom, browserSettingsAtom, usersAtom } from '@/lib/atoms'
|
|
||||||
import { getTodayInTimezone, isSameDate, t2d, d2t, getNow, d2s, getCompletionsForToday, isTaskOverdue, convertMachineReadableFrequencyToHumanReadable } from '@/lib/utils'
|
|
||||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Coins, Edit, Check, Undo2, MoreVertical, Pin } from 'lucide-react' // Removed unused icons
|
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
DropdownMenuItem,
|
DropdownMenuTrigger
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from '@/components/ui/dropdown-menu'
|
} from '@/components/ui/dropdown-menu'
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
import { useHabits } from '@/hooks/useHabits'
|
import { useHabits } from '@/hooks/useHabits'
|
||||||
import { INITIAL_RECURRENCE_RULE, RECURRENCE_RULE_MAP } from '@/lib/constants'
|
import { browserSettingsAtom, settingsAtom, usersAtom } from '@/lib/atoms'
|
||||||
import { DateTime } from 'luxon'
|
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar'
|
|
||||||
import { useHelpers } from '@/lib/client-helpers'
|
import { useHelpers } from '@/lib/client-helpers'
|
||||||
|
import { Habit, User } from '@/lib/types'
|
||||||
|
import { convertMachineReadableFrequencyToHumanReadable, getCompletionsForToday, isTaskOverdue } from '@/lib/utils'
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
|
import { Check, Coins, Edit, MoreVertical, Pin, Undo2 } from 'lucide-react'; // Removed unused icons
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
import { HabitContextMenuItems } from './HabitContextMenuItems'
|
import { HabitContextMenuItems } from './HabitContextMenuItems'
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar'
|
||||||
|
|
||||||
interface HabitItemProps {
|
interface HabitItemProps {
|
||||||
habit: Habit
|
habit: Habit
|
||||||
@@ -49,7 +45,6 @@ const renderUserAvatars = (habit: Habit, currentUser: User | null, usersData: {
|
|||||||
export default function HabitItem({ habit, onEdit, onDelete }: HabitItemProps) {
|
export default function HabitItem({ habit, onEdit, onDelete }: HabitItemProps) {
|
||||||
const { completeHabit, undoComplete, archiveHabit, unarchiveHabit, saveHabit } = useHabits()
|
const { completeHabit, undoComplete, archiveHabit, unarchiveHabit, saveHabit } = useHabits()
|
||||||
const [settings] = useAtom(settingsAtom)
|
const [settings] = useAtom(settingsAtom)
|
||||||
const [_, setPomo] = useAtom(pomodoroAtom)
|
|
||||||
const completionsToday = getCompletionsForToday({ habit, timezone: settings.system.timezone })
|
const completionsToday = getCompletionsForToday({ habit, timezone: settings.system.timezone })
|
||||||
const target = habit.targetCompletions || 1
|
const target = habit.targetCompletions || 1
|
||||||
const isCompletedToday = completionsToday >= target
|
const isCompletedToday = completionsToday >= target
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState, useMemo, useEffect } from 'react' // Added useMemo, useEffect
|
|
||||||
import { Plus, ArrowUpNarrowWide, ArrowDownWideNarrow, Search } from 'lucide-react' // Added sort icons, Search icon
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { habitsAtom, settingsAtom, browserSettingsAtom } from '@/lib/atoms'
|
|
||||||
import EmptyState from './EmptyState'
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import HabitItem from './HabitItem'
|
import { Input } from '@/components/ui/input'; // Added
|
||||||
|
import { Label } from '@/components/ui/label'; // Added
|
||||||
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; // Added
|
||||||
|
import { useHabits } from '@/hooks/useHabits'
|
||||||
|
import { browserSettingsAtom, habitsAtom } from '@/lib/atoms'
|
||||||
|
import { HabitIcon, TaskIcon } from '@/lib/constants'
|
||||||
|
import { Habit } from '@/lib/types'
|
||||||
|
import { getHabitFreq } from '@/lib/utils'; // Added
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
|
import { ArrowDownWideNarrow, ArrowUpNarrowWide, Plus, Search } from 'lucide-react'; // Added sort icons, Search icon
|
||||||
|
import { DateTime } from 'luxon'; // Added
|
||||||
|
import { useEffect, useMemo, useState } from 'react'; // Added useMemo, useEffect
|
||||||
import AddEditHabitModal from './AddEditHabitModal'
|
import AddEditHabitModal from './AddEditHabitModal'
|
||||||
import ConfirmDialog from './ConfirmDialog'
|
import ConfirmDialog from './ConfirmDialog'
|
||||||
import { Habit } from '@/lib/types'
|
import EmptyState from './EmptyState'
|
||||||
import { useHabits } from '@/hooks/useHabits'
|
import HabitItem from './HabitItem'
|
||||||
import { HabitIcon, TaskIcon } from '@/lib/constants'
|
|
||||||
import { ViewToggle } from './ViewToggle'
|
import { ViewToggle } from './ViewToggle'
|
||||||
import { Input } from '@/components/ui/input' // Added
|
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' // Added
|
|
||||||
import { Label } from '@/components/ui/label' // Added
|
|
||||||
import { DateTime } from 'luxon' // Added
|
|
||||||
import { getHabitFreq } from '@/lib/utils' // Added
|
|
||||||
|
|
||||||
export default function HabitList() {
|
export default function HabitList() {
|
||||||
const { saveHabit, deleteHabit } = useHabits()
|
const { saveHabit, deleteHabit } = useHabits()
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { Habit } from '@/lib/types'
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
import { d2s, getNow, t2d } from '@/lib/utils' // Removed getCompletedHabitsForDate
|
import { completedHabitsMapAtom, hasTasksAtom, settingsAtom } from '@/lib/atoms'; // Added completedHabitsMapAtom
|
||||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'
|
import { Habit } from '@/lib/types'
|
||||||
|
import { d2s, getNow } from '@/lib/utils'; // Removed getCompletedHabitsForDate
|
||||||
import { useAtom } from 'jotai'
|
import { useAtom } from 'jotai'
|
||||||
import { settingsAtom, hasTasksAtom, completedHabitsMapAtom } from '@/lib/atoms' // Added completedHabitsMapAtom
|
import { CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'
|
||||||
|
|
||||||
interface HabitStreakProps {
|
interface HabitStreakProps {
|
||||||
habits: Habit[]
|
habits: Habit[]
|
||||||
|
|||||||
@@ -1,26 +1,15 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { coinsAtom, settingsAtom, browserSettingsAtom } from '@/lib/atoms'
|
|
||||||
import { useCoins } from '@/hooks/useCoins'
|
|
||||||
import { FormattedNumber } from '@/components/FormattedNumber'
|
import { FormattedNumber } from '@/components/FormattedNumber'
|
||||||
import { Menu, Settings, User, Info, Coins } from 'lucide-react'
|
|
||||||
import { Button } from '@/components/ui/button'
|
|
||||||
import { Logo } from '@/components/Logo'
|
import { Logo } from '@/components/Logo'
|
||||||
import NotificationBell from './NotificationBell'
|
import { useCoins } from '@/hooks/useCoins'
|
||||||
import {
|
import { settingsAtom } from '@/lib/atoms'
|
||||||
DropdownMenu,
|
import { useAtom } from 'jotai'
|
||||||
DropdownMenuContent,
|
import { Coins } from 'lucide-react'
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from '@/components/ui/dropdown-menu'
|
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
|
||||||
import AboutModal from './AboutModal'
|
|
||||||
import Link from 'next/link'
|
|
||||||
import dynamic from 'next/dynamic'
|
import dynamic from 'next/dynamic'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import NotificationBell from './NotificationBell'
|
||||||
import { Profile } from './Profile'
|
import { Profile } from './Profile'
|
||||||
import { useHelpers } from '@/lib/client-helpers'
|
|
||||||
|
|
||||||
interface HeaderProps {
|
interface HeaderProps {
|
||||||
className?: string
|
className?: string
|
||||||
@@ -30,7 +19,6 @@ const TodayEarnedCoins = dynamic(() => import('./TodayEarnedCoins'), { ssr: fals
|
|||||||
|
|
||||||
export default function Header({ className }: HeaderProps) {
|
export default function Header({ className }: HeaderProps) {
|
||||||
const [settings] = useAtom(settingsAtom)
|
const [settings] = useAtom(settingsAtom)
|
||||||
const [browserSettings] = useAtom(browserSettingsAtom)
|
|
||||||
const { balance } = useCoins()
|
const { balance } = useCoins()
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { Sparkles } from "lucide-react"
|
|
||||||
|
|
||||||
export function Logo() {
|
export function Logo() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import Link from 'next/link'
|
|
||||||
import { Home, Calendar, List, Gift, Coins, Settings, Info, CheckSquare } from 'lucide-react'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { browserSettingsAtom } from '@/lib/atoms'
|
import { browserSettingsAtom } from '@/lib/atoms'
|
||||||
|
import { useHelpers } from '@/lib/client-helpers'
|
||||||
|
import { HabitIcon, TaskIcon } from '@/lib/constants'
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
|
import { Calendar, Coins, Gift, Home } from 'lucide-react'
|
||||||
|
import Link from 'next/link'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import AboutModal from './AboutModal'
|
import AboutModal from './AboutModal'
|
||||||
import { HabitIcon, TaskIcon } from '@/lib/constants'
|
|
||||||
import { useHelpers } from '@/lib/client-helpers'
|
|
||||||
|
|
||||||
type ViewPort = 'main' | 'mobile'
|
type ViewPort = 'main' | 'mobile'
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
import React from 'react';
|
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
||||||
|
import { DropdownMenuItem } from '@/components/ui/dropdown-menu';
|
||||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||||
import { Separator } from '@/components/ui/separator';
|
import { Separator } from '@/components/ui/separator';
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
|
||||||
import { CoinsData, HabitsData, WishlistData, UserData, User, CoinTransaction } from '@/lib/types';
|
|
||||||
import { t2d } from '@/lib/utils';
|
|
||||||
import Link from 'next/link';
|
|
||||||
import { DropdownMenuItem } from '@/components/ui/dropdown-menu';
|
|
||||||
import { Info } from 'lucide-react';
|
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from '@/components/ui/tooltip';
|
} from '@/components/ui/tooltip';
|
||||||
|
import { CoinTransaction, HabitsData, User, UserData, WishlistData } from '@/lib/types';
|
||||||
|
import { t2d } from '@/lib/utils';
|
||||||
|
import { Info } from 'lucide-react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
interface NotificationDropdownProps {
|
interface NotificationDropdownProps {
|
||||||
currentUser: User | null;
|
currentUser: User | null;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar';
|
|
||||||
import { Input } from './ui/input';
|
|
||||||
import { Button } from './ui/button';
|
|
||||||
import { Label } from './ui/label';
|
|
||||||
import { User as UserIcon } from 'lucide-react';
|
|
||||||
import { Permission, User } from '@/lib/types';
|
|
||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
|
import { User } from '@/lib/types';
|
||||||
|
import { User as UserIcon } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar';
|
||||||
|
import { Button } from './ui/button';
|
||||||
|
import { Input } from './ui/input';
|
||||||
|
import { Label } from './ui/label';
|
||||||
|
|
||||||
interface PasswordEntryFormProps {
|
interface PasswordEntryFormProps {
|
||||||
user: User;
|
user: User;
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState, useEffect, useRef, useCallback } from 'react'
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Progress } from '@/components/ui/progress'
|
import { Progress } from '@/components/ui/progress'
|
||||||
import { Play, Pause, RotateCw, Minus, X, Clock, SkipForward } from 'lucide-react'
|
|
||||||
import { cn, getCompletionsForToday } from '@/lib/utils'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { settingsAtom, pomodoroAtom, habitsAtom, pomodoroTodayCompletionsAtom } from '@/lib/atoms'
|
|
||||||
import { getCompletionsForDate, getTodayInTimezone } from '@/lib/utils'
|
|
||||||
import { useHabits } from '@/hooks/useHabits'
|
import { useHabits } from '@/hooks/useHabits'
|
||||||
|
import { habitsAtom, pomodoroAtom, pomodoroTodayCompletionsAtom, settingsAtom } from '@/lib/atoms'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
|
import { Clock, Minus, Pause, Play, RotateCw, SkipForward, X } from 'lucide-react'
|
||||||
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
|
||||||
interface PomoConfig {
|
interface PomoConfig {
|
||||||
labels: string[]
|
labels: string[]
|
||||||
@@ -135,20 +134,6 @@ export default function PomodoroTimer() {
|
|||||||
const remaining = Math.floor((targetEndTime - Date.now()) / 1000)
|
const remaining = Math.floor((targetEndTime - Date.now()) / 1000)
|
||||||
|
|
||||||
if (remaining <= 0) {
|
if (remaining <= 0) {
|
||||||
handleTimerEnd()
|
|
||||||
} else {
|
|
||||||
setTimeLeft(remaining)
|
|
||||||
}
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
// return handles any other states
|
|
||||||
return () => {
|
|
||||||
if (interval) clearInterval(interval)
|
|
||||||
}
|
|
||||||
}, [state])
|
|
||||||
|
|
||||||
const handleTimerEnd = async () => {
|
|
||||||
setState("stopped")
|
setState("stopped")
|
||||||
const currentTimerType = currentTimer.current.type
|
const currentTimerType = currentTimer.current.type
|
||||||
currentTimer.current = currentTimerType === 'focus' ? PomoConfigs.break : PomoConfigs.focus
|
currentTimer.current = currentTimerType === 'focus' ? PomoConfigs.break : PomoConfigs.focus
|
||||||
@@ -159,10 +144,20 @@ export default function PomodoroTimer() {
|
|||||||
|
|
||||||
// update habits only after focus sessions
|
// update habits only after focus sessions
|
||||||
if (selectedHabit && currentTimerType === 'focus') {
|
if (selectedHabit && currentTimerType === 'focus') {
|
||||||
await completeHabit(selectedHabit)
|
completeHabit(selectedHabit)
|
||||||
// The atom will automatically update with the new completions
|
// The atom will automatically update with the new completions
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setTimeLeft(remaining)
|
||||||
}
|
}
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return handles any other states
|
||||||
|
return () => {
|
||||||
|
if (interval) clearInterval(interval)
|
||||||
|
}
|
||||||
|
}, [state, timeLeft, completeHabit, selectedHabit])
|
||||||
|
|
||||||
const toggleTimer = () => {
|
const toggleTimer = () => {
|
||||||
setState(prev => prev === 'started' ? 'paused' : 'started')
|
setState(prev => prev === 'started' ? 'paused' : 'started')
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import { signOut } from "@/app/actions/user"
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
|
||||||
import { Settings, Info, User, Moon, Sun, Palette, ArrowRightLeft, LogOut, Crown } from "lucide-react"
|
import { toast } from "@/hooks/use-toast"
|
||||||
|
import { settingsAtom, userSelectAtom } from "@/lib/atoms"
|
||||||
|
import { useHelpers } from "@/lib/client-helpers"
|
||||||
|
import { useAtom } from "jotai"
|
||||||
|
import { ArrowRightLeft, Crown, Info, LogOut, Moon, Palette, Settings, Sun, User } from "lucide-react"
|
||||||
|
import { useTheme } from "next-themes"
|
||||||
|
import Link from "next/link"
|
||||||
|
import { useState } from "react"
|
||||||
|
import AboutModal from "./AboutModal"
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from './ui/dialog'
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from './ui/dialog'
|
||||||
import UserForm from './UserForm'
|
import UserForm from './UserForm'
|
||||||
import Link from "next/link"
|
|
||||||
import { useAtom } from "jotai"
|
|
||||||
import { settingsAtom, userSelectAtom } from "@/lib/atoms"
|
|
||||||
import AboutModal from "./AboutModal"
|
|
||||||
import { useEffect, useState } from "react"
|
|
||||||
import { useTheme } from "next-themes"
|
|
||||||
import { signOut } from "@/app/actions/user"
|
|
||||||
import { toast } from "@/hooks/use-toast"
|
|
||||||
import { useHelpers } from "@/lib/client-helpers"
|
|
||||||
|
|
||||||
export function Profile() {
|
export function Profile() {
|
||||||
const [settings] = useAtom(settingsAtom)
|
const [settings] = useAtom(settingsAtom)
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { createUser, updateUser, updateUserPassword, uploadAvatar } from '@/app/actions/data';
|
||||||
|
import { toast } from '@/hooks/use-toast';
|
||||||
|
import { serverSettingsAtom, usersAtom } from '@/lib/atoms';
|
||||||
|
import { useHelpers } from '@/lib/client-helpers';
|
||||||
|
import { Permission } from '@/lib/types';
|
||||||
import { passwordSchema, usernameSchema } from '@/lib/zod';
|
import { passwordSchema, usernameSchema } from '@/lib/zod';
|
||||||
import { Input } from './ui/input';
|
import { useAtom, useAtomValue } from 'jotai';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { User as UserIcon } from 'lucide-react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { PermissionSelector } from './PermissionSelector';
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar';
|
||||||
import { Button } from './ui/button';
|
import { Button } from './ui/button';
|
||||||
|
import { Input } from './ui/input';
|
||||||
import { Label } from './ui/label';
|
import { Label } from './ui/label';
|
||||||
import { Switch } from './ui/switch';
|
import { Switch } from './ui/switch';
|
||||||
import { Permission } from '@/lib/types';
|
|
||||||
import { toast } from '@/hooks/use-toast';
|
|
||||||
import { useAtom, useAtomValue } from 'jotai';
|
|
||||||
import { serverSettingsAtom, usersAtom } from '@/lib/atoms';
|
|
||||||
import { createUser, updateUser, updateUserPassword, uploadAvatar } from '@/app/actions/data';
|
|
||||||
import { SafeUser, User } from '@/lib/types';
|
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar';
|
|
||||||
import { User as UserIcon } from 'lucide-react';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { PermissionSelector } from './PermissionSelector';
|
|
||||||
import { useHelpers } from '@/lib/client-helpers';
|
|
||||||
|
|
||||||
interface UserFormProps {
|
interface UserFormProps {
|
||||||
userId?: string; // if provided, we're editing; if not, we're creating
|
userId?: string; // if provided, we're editing; if not, we're creating
|
||||||
|
|||||||
@@ -1,22 +1,19 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { signIn } from '@/app/actions/user';
|
||||||
|
import { toast } from '@/hooks/use-toast';
|
||||||
|
import { usersAtom } from '@/lib/atoms';
|
||||||
|
import { useHelpers } from '@/lib/client-helpers';
|
||||||
|
import { SafeUser, User } from '@/lib/types';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
import { Description } from '@radix-ui/react-dialog';
|
||||||
|
import { useAtom } from 'jotai';
|
||||||
|
import { Crown, Plus, User as UserIcon, UserRoundPen } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import PasswordEntryForm from './PasswordEntryForm';
|
import PasswordEntryForm from './PasswordEntryForm';
|
||||||
import UserForm from './UserForm';
|
import UserForm from './UserForm';
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from './ui/dialog';
|
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar';
|
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar';
|
||||||
import { Crown, Pencil, Plus, User as UserIcon, UserRoundPen } from 'lucide-react';
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from './ui/dialog';
|
||||||
import { Input } from './ui/input';
|
|
||||||
import { Button } from './ui/button';
|
|
||||||
import { useAtom } from 'jotai';
|
|
||||||
import { usersAtom } from '@/lib/atoms';
|
|
||||||
import { signIn } from '@/app/actions/user';
|
|
||||||
import { createUser } from '@/app/actions/data';
|
|
||||||
import { toast } from '@/hooks/use-toast';
|
|
||||||
import { Description } from '@radix-ui/react-dialog';
|
|
||||||
import { SafeUser, User } from '@/lib/types';
|
|
||||||
import { cn } from '@/lib/utils';
|
|
||||||
import { useHelpers } from '@/lib/client-helpers';
|
|
||||||
|
|
||||||
function UserCard({
|
function UserCard({
|
||||||
user,
|
user,
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { cn } from '@/lib/utils'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { CheckSquare, ListChecks } from 'lucide-react'
|
|
||||||
import { browserSettingsAtom, habitsAtom, settingsAtom } from '@/lib/atoms'
|
import { browserSettingsAtom, habitsAtom, settingsAtom } from '@/lib/atoms'
|
||||||
import type { ViewType } from '@/lib/types'
|
|
||||||
import { HabitIcon, TaskIcon } from '@/lib/constants'
|
import { HabitIcon, TaskIcon } from '@/lib/constants'
|
||||||
import { isHabitDueToday } from '@/lib/utils'
|
import type { ViewType } from '@/lib/types'
|
||||||
|
import { cn, isHabitDueToday } from '@/lib/utils'
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
import { NotificationBadge } from './ui/notification-badge'
|
import { NotificationBadge } from './ui/notification-badge'
|
||||||
|
|
||||||
interface ViewToggleProps {
|
interface ViewToggleProps {
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
import { WishlistItemType, User, Permission } from '@/lib/types'
|
|
||||||
import { useAtom } from 'jotai'
|
|
||||||
import { usersAtom } from '@/lib/atoms'
|
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar'
|
|
||||||
import { useHelpers } from '@/lib/client-helpers'
|
|
||||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
|
|
||||||
import ReactMarkdown from 'react-markdown'
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Coins, Edit, Trash2, Gift, MoreVertical, Archive, ArchiveRestore } from 'lucide-react'
|
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
@@ -14,6 +7,12 @@ import {
|
|||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@/components/ui/dropdown-menu'
|
} from '@/components/ui/dropdown-menu'
|
||||||
|
import { usersAtom } from '@/lib/atoms'
|
||||||
|
import { useHelpers } from '@/lib/client-helpers'
|
||||||
|
import { User, WishlistItemType } from '@/lib/types'
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
|
import { Archive, ArchiveRestore, Coins, Edit, Gift, MoreVertical, Trash2 } from 'lucide-react'
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar'
|
||||||
|
|
||||||
interface WishlistItemProps {
|
interface WishlistItemProps {
|
||||||
item: WishlistItemType
|
item: WishlistItemType
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import * as React from "react"
|
import { Moon, Sun } from "lucide-react"
|
||||||
import { Moon, MoonIcon, Sun } from "lucide-react"
|
|
||||||
import { useTheme } from "next-themes"
|
import { useTheme } from "next-themes"
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
|
|||||||
39
lib/atoms.ts
39
lib/atoms.ts
@@ -1,35 +1,30 @@
|
|||||||
import { atom } from "jotai";
|
|
||||||
import {
|
import {
|
||||||
getDefaultSettings,
|
|
||||||
getDefaultHabitsData,
|
|
||||||
getDefaultCoinsData,
|
|
||||||
getDefaultWishlistData,
|
|
||||||
Habit,
|
|
||||||
ViewType,
|
|
||||||
getDefaultUsersData,
|
|
||||||
CompletionCache,
|
|
||||||
getDefaultServerSettings,
|
|
||||||
User,
|
|
||||||
} from "./types";
|
|
||||||
import {
|
|
||||||
getTodayInTimezone,
|
|
||||||
isSameDate,
|
|
||||||
t2d,
|
|
||||||
calculateCoinsEarnedToday,
|
calculateCoinsEarnedToday,
|
||||||
|
calculateCoinsSpentToday,
|
||||||
calculateTotalEarned,
|
calculateTotalEarned,
|
||||||
calculateTotalSpent,
|
calculateTotalSpent,
|
||||||
calculateCoinsSpentToday,
|
|
||||||
calculateTransactionsToday,
|
calculateTransactionsToday,
|
||||||
getCompletionsForToday,
|
getCompletionsForToday,
|
||||||
getISODate,
|
getHabitFreq,
|
||||||
isHabitDueToday,
|
getTodayInTimezone,
|
||||||
getNow,
|
|
||||||
isHabitDue,
|
isHabitDue,
|
||||||
getHabitFreq
|
t2d
|
||||||
} from "@/lib/utils";
|
} from "@/lib/utils";
|
||||||
|
import { atom } from "jotai";
|
||||||
import { atomFamily, atomWithStorage } from "jotai/utils";
|
import { atomFamily, atomWithStorage } from "jotai/utils";
|
||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
import { Freq } from "./types";
|
import {
|
||||||
|
CompletionCache,
|
||||||
|
Freq,
|
||||||
|
getDefaultCoinsData,
|
||||||
|
getDefaultHabitsData,
|
||||||
|
getDefaultServerSettings,
|
||||||
|
getDefaultSettings,
|
||||||
|
getDefaultUsersData,
|
||||||
|
getDefaultWishlistData,
|
||||||
|
Habit,
|
||||||
|
ViewType
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
export interface BrowserSettings {
|
export interface BrowserSettings {
|
||||||
viewType: ViewType
|
viewType: ViewType
|
||||||
|
|||||||
Reference in New Issue
Block a user