Add flexible date pickers and export options to stock dashboard

Introduces a reusable date picker component with support for single date, date range, and month selection. Updates the stock management page to allow exporting reports by daily, weekly, monthly, or custom date ranges using the new pickers. Refactors promotion form to use the new date picker for start and end dates. Adds more business quotes to the quotes config.
This commit is contained in:
NotII
2025-07-30 00:38:25 +02:00
parent 48cfd45fb1
commit 1b51f29c24
5 changed files with 575 additions and 39 deletions

View File

@@ -33,6 +33,9 @@ import { Product } from "@/models/products";
import { Package, RefreshCw, ChevronDown, CheckSquare, XSquare, Boxes, Download, Calendar } from "lucide-react"; import { Package, RefreshCw, ChevronDown, CheckSquare, XSquare, Boxes, Download, Calendar } from "lucide-react";
import { clientFetch } from "@/lib/api"; import { clientFetch } from "@/lib/api";
import { toast } from "sonner"; import { toast } from "sonner";
import { DatePicker, DateRangePicker, DateRangeDisplay, MonthPicker } from "@/components/ui/date-picker";
import { DateRange } from "react-day-picker";
import { addDays, startOfDay, endOfDay, format, isSameDay } from "date-fns";
interface StockData { interface StockData {
currentStock: number; currentStock: number;
@@ -40,6 +43,8 @@ interface StockData {
lowStockThreshold?: number; lowStockThreshold?: number;
} }
type ReportType = 'daily' | 'weekly' | 'monthly' | 'custom';
export default function StockManagementPage() { export default function StockManagementPage() {
const router = useRouter(); const router = useRouter();
const [products, setProducts] = useState<Product[]>([]); const [products, setProducts] = useState<Product[]>([]);
@@ -50,7 +55,15 @@ export default function StockManagementPage() {
const [selectedProducts, setSelectedProducts] = useState<string[]>([]); const [selectedProducts, setSelectedProducts] = useState<string[]>([]);
const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false); const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false);
const [bulkAction, setBulkAction] = useState<'enable' | 'disable' | null>(null); const [bulkAction, setBulkAction] = useState<'enable' | 'disable' | null>(null);
// Export state
const [exportDate, setExportDate] = useState<string>(new Date().toISOString().split('T')[0]); const [exportDate, setExportDate] = useState<string>(new Date().toISOString().split('T')[0]);
const [exportDateRange, setExportDateRange] = useState<DateRange | undefined>({
from: startOfDay(addDays(new Date(), -6)),
to: endOfDay(new Date())
});
const [selectedMonth, setSelectedMonth] = useState<Date>(new Date());
const [reportType, setReportType] = useState<ReportType>('daily');
const [isExporting, setIsExporting] = useState<boolean>(false); const [isExporting, setIsExporting] = useState<boolean>(false);
useEffect(() => { useEffect(() => {
@@ -259,7 +272,47 @@ export default function StockManagementPage() {
const handleExportStock = async () => { const handleExportStock = async () => {
setIsExporting(true); setIsExporting(true);
try { try {
const response = await clientFetch(`/api/analytics/daily-stock-report?date=${exportDate}`); let response;
let filename;
switch (reportType) {
case 'daily':
response = await clientFetch(`/api/analytics/daily-stock-report?date=${exportDate}`);
filename = `daily-stock-report-${exportDate}.csv`;
break;
case 'weekly':
if (!exportDateRange?.from) {
toast.error('Please select a date range for weekly report');
return;
}
const weekStart = format(exportDateRange.from, 'yyyy-MM-dd');
response = await clientFetch(`/api/analytics/weekly-stock-report?weekStart=${weekStart}`);
filename = `weekly-stock-report-${weekStart}.csv`;
break;
case 'monthly':
const year = selectedMonth.getFullYear();
const month = selectedMonth.getMonth() + 1;
response = await clientFetch(`/api/analytics/monthly-stock-report?year=${year}&month=${month}`);
filename = `monthly-stock-report-${year}-${month.toString().padStart(2, '0')}.csv`;
break;
case 'custom':
if (!exportDateRange?.from || !exportDateRange?.to) {
toast.error('Please select a date range for custom report');
return;
}
const startDate = format(exportDateRange.from, 'yyyy-MM-dd');
const endDate = format(exportDateRange.to, 'yyyy-MM-dd');
response = await clientFetch(`/api/analytics/daily-stock-report?startDate=${startDate}&endDate=${endDate}`);
filename = `custom-stock-report-${startDate}-to-${endDate}.csv`;
break;
default:
toast.error('Invalid report type');
return;
}
if (!response || !response.products) { if (!response || !response.products) {
throw new Error('No data received from server'); throw new Error('No data received from server');
@@ -297,14 +350,19 @@ export default function StockManagementPage() {
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
link.setAttribute('href', url); link.setAttribute('href', url);
link.setAttribute('download', `daily-stock-report-${exportDate}.csv`); link.setAttribute('download', filename);
link.style.visibility = 'hidden'; link.style.visibility = 'hidden';
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
toast.success(`Stock report for ${exportDate} exported successfully`); const periodText = reportType === 'daily' ? exportDate :
reportType === 'weekly' ? `week starting ${format(exportDateRange?.from || new Date(), 'MMM dd')}` :
reportType === 'monthly' ? `${response.monthName || 'current month'}` :
`${format(exportDateRange?.from || new Date(), 'MMM dd')} to ${format(exportDateRange?.to || new Date(), 'MMM dd')}`;
toast.success(`${reportType.charAt(0).toUpperCase() + reportType.slice(1)} stock report for ${periodText} exported successfully`);
} catch (error) { } catch (error) {
console.error('Error exporting stock report:', error); console.error('Error exporting stock report:', error);
toast.error('Failed to export stock report'); toast.error('Failed to export stock report');
@@ -348,28 +406,60 @@ export default function StockManagementPage() {
value={searchTerm} value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)} onChange={(e) => setSearchTerm(e.target.value)}
/> />
<Popover>
<PopoverTrigger asChild> {/* Report Type Selector */}
<Button <DropdownMenu>
variant="outline" <DropdownMenuTrigger asChild>
className="gap-2" <Button variant="outline" className="gap-2">
>
<Calendar className="h-4 w-4" /> <Calendar className="h-4 w-4" />
{exportDate} {reportType.charAt(0).toUpperCase() + reportType.slice(1)} Report
<ChevronDown className="h-4 w-4" />
</Button> </Button>
</PopoverTrigger> </DropdownMenuTrigger>
<PopoverContent className="w-auto p-3" align="end"> <DropdownMenuContent>
<div className="space-y-2"> <DropdownMenuItem onClick={() => setReportType('daily')}>
<label className="text-sm font-medium">Select Date for Export</label> Daily Report
<Input </DropdownMenuItem>
type="date" <DropdownMenuItem onClick={() => setReportType('weekly')}>
value={exportDate} Weekly Report
onChange={(e) => setExportDate(e.target.value)} </DropdownMenuItem>
className="w-full" <DropdownMenuItem onClick={() => setReportType('monthly')}>
/> Monthly Report
</div> </DropdownMenuItem>
</PopoverContent> <DropdownMenuItem onClick={() => setReportType('custom')}>
</Popover> Custom Range
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
{/* Date Selection based on report type */}
{reportType === 'daily' && (
<DatePicker
date={exportDate ? new Date(exportDate) : undefined}
onDateChange={(date) => setExportDate(date ? date.toISOString().split('T')[0] : '')}
placeholder="Select export date"
className="w-auto"
/>
)}
{(reportType === 'weekly' || reportType === 'custom') && (
<DateRangePicker
dateRange={exportDateRange}
onDateRangeChange={setExportDateRange}
placeholder="Select date range"
className="w-auto"
/>
)}
{reportType === 'monthly' && (
<MonthPicker
selectedMonth={selectedMonth}
onMonthChange={(date) => setSelectedMonth(date || new Date())}
placeholder="Select month"
className="w-auto"
/>
)}
<Button <Button
variant="outline" variant="outline"
onClick={handleExportStock} onClick={handleExportStock}
@@ -383,6 +473,7 @@ export default function StockManagementPage() {
)} )}
{isExporting ? 'Exporting...' : 'Export CSV'} {isExporting ? 'Exporting...' : 'Export CSV'}
</Button> </Button>
{selectedProducts.length > 0 && ( {selectedProducts.length > 0 && (
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>

View File

@@ -22,6 +22,7 @@ import { Textarea } from '@/components/ui/textarea';
import { toast } from '@/components/ui/use-toast'; import { toast } from '@/components/ui/use-toast';
import { PromotionFormData } from '@/lib/types/promotion'; import { PromotionFormData } from '@/lib/types/promotion';
import { fetchClient } from '@/lib/api'; import { fetchClient } from '@/lib/api';
import { DatePicker } from '@/components/ui/date-picker';
// Form schema validation with Zod // Form schema validation with Zod
const formSchema = z.object({ const formSchema = z.object({
@@ -246,7 +247,12 @@ export default function NewPromotionForm({ onSuccess, onCancel }: NewPromotionFo
<FormItem> <FormItem>
<FormLabel className="text-sm font-medium">Start Date</FormLabel> <FormLabel className="text-sm font-medium">Start Date</FormLabel>
<FormControl> <FormControl>
<Input type="date" className="h-10" {...field} /> <DatePicker
date={field.value ? new Date(field.value) : undefined}
onDateChange={(date) => field.onChange(date ? date.toISOString().split('T')[0] : '')}
placeholder="Select start date"
className="h-10"
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@@ -260,15 +266,11 @@ export default function NewPromotionForm({ onSuccess, onCancel }: NewPromotionFo
<FormItem> <FormItem>
<FormLabel className="text-sm font-medium">End Date (Optional)</FormLabel> <FormLabel className="text-sm font-medium">End Date (Optional)</FormLabel>
<FormControl> <FormControl>
<Input <DatePicker
type="date" date={field.value ? new Date(field.value) : undefined}
onDateChange={(date) => field.onChange(date ? date.toISOString().split('T')[0] : null)}
placeholder="Select end date (optional)"
className="h-10" className="h-10"
{...field}
value={field.value || ''}
onChange={(e) => {
const value = e.target.value;
field.onChange(value === '' ? null : value);
}}
/> />
</FormControl> </FormControl>
<FormDescription className="text-xs"> <FormDescription className="text-xs">

View File

@@ -75,7 +75,6 @@ export default function BroadcastDialog({ open, setOpen }: BroadcastDialogProps)
const newText = textarea.value.substring(0, start) + insertText + textarea.value.substring(end); const newText = textarea.value.substring(0, start) + insertText + textarea.value.substring(end);
setBroadcastMessage(newText); setBroadcastMessage(newText);
// Set cursor position after the inserted text
const newCursorPos = start + insertText.length; const newCursorPos = start + insertText.length;
textarea.focus(); textarea.focus();
textarea.setSelectionRange(newCursorPos, newCursorPos); textarea.setSelectionRange(newCursorPos, newCursorPos);

View File

@@ -0,0 +1,417 @@
"use client"
import * as React from "react"
import { format, addDays, startOfDay, endOfDay, isSameDay, isWithinInterval, getMonth, getYear, setMonth, setYear } from "date-fns"
import { Calendar as CalendarIcon, ChevronLeft, ChevronRight, X } from "lucide-react"
import { DateRange } from "react-day-picker"
import { cn } from "@/lib/utils/styles"
import { Button } from "@/components/ui/button"
import { Calendar } from "@/components/ui/calendar"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
import { Badge } from "@/components/ui/badge"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
interface DatePickerProps {
date?: Date
onDateChange?: (date: Date | undefined) => void
placeholder?: string
className?: string
}
interface DateRangePickerProps {
dateRange?: DateRange
onDateRangeChange?: (range: DateRange | undefined) => void
placeholder?: string
className?: string
showPresets?: boolean
disabled?: boolean
}
interface MonthPickerProps {
selectedMonth?: Date
onMonthChange?: (date: Date | undefined) => void
placeholder?: string
className?: string
disabled?: boolean
}
// Single Date Picker
export function DatePicker({ date, onDateChange, placeholder = "Pick a date", className }: DatePickerProps) {
return (
<Popover>
<PopoverTrigger asChild>
<Button
variant={"outline"}
className={cn(
"w-full justify-start text-left font-normal",
!date && "text-muted-foreground",
className
)}
>
<CalendarIcon className="mr-2 h-4 w-4" />
{date ? format(date, "PPP") : placeholder}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
selected={date}
onSelect={onDateChange}
initialFocus
/>
</PopoverContent>
</Popover>
)
}
// Month Picker Component
export function MonthPicker({ selectedMonth, onMonthChange, placeholder = "Pick a month", className, disabled = false }: MonthPickerProps) {
const [isOpen, setIsOpen] = React.useState(false)
const [selectedYear, setSelectedYear] = React.useState(selectedMonth ? getYear(selectedMonth) : new Date().getFullYear())
const [selectedMonthIndex, setSelectedMonthIndex] = React.useState(selectedMonth ? getMonth(selectedMonth) : new Date().getMonth())
const months = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
]
const years = Array.from({ length: 10 }, (_, i) => new Date().getFullYear() - 5 + i)
React.useEffect(() => {
if (selectedMonth) {
setSelectedYear(getYear(selectedMonth))
setSelectedMonthIndex(getMonth(selectedMonth))
}
}, [selectedMonth])
const handleMonthSelect = (monthIndex: number) => {
const newDate = new Date(selectedYear, monthIndex, 1)
onMonthChange?.(newDate)
setIsOpen(false)
}
const handleYearChange = (year: string) => {
const newYear = parseInt(year)
setSelectedYear(newYear)
if (selectedMonth) {
const newDate = new Date(newYear, selectedMonthIndex, 1)
onMonthChange?.(newDate)
}
}
const formatSelectedMonth = (date?: Date) => {
if (!date) return placeholder
return format(date, "MMMM yyyy")
}
return (
<Popover open={isOpen} onOpenChange={setIsOpen}>
<PopoverTrigger asChild>
<Button
variant={"outline"}
className={cn(
"w-full justify-start text-left font-normal",
!selectedMonth && "text-muted-foreground",
className
)}
disabled={disabled}
>
<CalendarIcon className="mr-2 h-4 w-4" />
{formatSelectedMonth(selectedMonth)}
{selectedMonth && (
<Button
variant="ghost"
size="sm"
className="ml-auto h-6 w-6 p-0 hover:bg-transparent"
onClick={(e) => {
e.stopPropagation()
onMonthChange?.(undefined)
}}
>
<X className="h-3 w-3" />
</Button>
)}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-4" align="start">
<div className="space-y-4">
<div className="flex items-center justify-between">
<h4 className="font-medium">Select Month</h4>
<Select value={selectedYear.toString()} onValueChange={handleYearChange}>
<SelectTrigger className="w-24">
<SelectValue />
</SelectTrigger>
<SelectContent>
{years.map((year) => (
<SelectItem key={year} value={year.toString()}>
{year}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="grid grid-cols-3 gap-2">
{months.map((month, index) => (
<Button
key={month}
variant={selectedMonthIndex === index ? "default" : "outline"}
size="sm"
onClick={() => handleMonthSelect(index)}
className="text-xs"
>
{month}
</Button>
))}
</div>
</div>
</PopoverContent>
</Popover>
)
}
// Date Range Picker with Presets
export function DateRangePicker({
dateRange,
onDateRangeChange,
placeholder = "Pick a date range",
className,
showPresets = true,
disabled = false
}: DateRangePickerProps) {
const [isOpen, setIsOpen] = React.useState(false)
const presets = [
{
label: "Today",
value: {
from: startOfDay(new Date()),
to: endOfDay(new Date())
}
},
{
label: "Yesterday",
value: {
from: startOfDay(addDays(new Date(), -1)),
to: endOfDay(addDays(new Date(), -1))
}
},
{
label: "Last 7 days",
value: {
from: startOfDay(addDays(new Date(), -6)),
to: endOfDay(new Date())
}
},
{
label: "Last 30 days",
value: {
from: startOfDay(addDays(new Date(), -29)),
to: endOfDay(new Date())
}
},
{
label: "This month",
value: {
from: startOfDay(new Date(new Date().getFullYear(), new Date().getMonth(), 1)),
to: endOfDay(new Date())
}
},
{
label: "Last month",
value: {
from: startOfDay(new Date(new Date().getFullYear(), new Date().getMonth() - 1, 1)),
to: endOfDay(new Date(new Date().getFullYear(), new Date().getMonth(), 0))
}
}
]
const handlePresetClick = (preset: typeof presets[0]) => {
onDateRangeChange?.(preset.value)
setIsOpen(false)
}
const handleClear = () => {
onDateRangeChange?.(undefined)
setIsOpen(false)
}
const formatDateRange = (range: DateRange | undefined) => {
if (!range?.from) return placeholder
if (!range.to) {
return format(range.from, "PPP")
}
if (isSameDay(range.from, range.to)) {
return format(range.from, "PPP")
}
return `${format(range.from, "MMM dd")} - ${format(range.to, "MMM dd, yyyy")}`
}
return (
<Popover open={isOpen} onOpenChange={setIsOpen}>
<PopoverTrigger asChild>
<Button
variant={"outline"}
className={cn(
"w-full justify-start text-left font-normal",
!dateRange?.from && "text-muted-foreground",
className
)}
disabled={disabled}
>
<CalendarIcon className="mr-2 h-4 w-4" />
{formatDateRange(dateRange)}
{dateRange?.from && (
<Button
variant="ghost"
size="sm"
className="ml-auto h-6 w-6 p-0 hover:bg-transparent"
onClick={(e) => {
e.stopPropagation()
handleClear()
}}
>
<X className="h-3 w-3" />
</Button>
)}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<div className="p-3">
{showPresets && (
<div className="space-y-2 mb-4">
<Label className="text-sm font-medium">Quick Select</Label>
<div className="grid grid-cols-2 gap-2">
{presets.map((preset) => (
<Button
key={preset.label}
variant="outline"
size="sm"
className="text-xs h-8"
onClick={() => handlePresetClick(preset)}
>
{preset.label}
</Button>
))}
</div>
</div>
)}
<Calendar
initialFocus
mode="range"
defaultMonth={dateRange?.from}
selected={dateRange}
onSelect={onDateRangeChange}
numberOfMonths={2}
className="rounded-md border"
/>
</div>
</PopoverContent>
</Popover>
)
}
// Custom Date Range Input Component
export function CustomDateRangeInput({
dateRange,
onDateRangeChange,
className
}: DateRangePickerProps) {
const [fromDate, setFromDate] = React.useState<string>("")
const [toDate, setToDate] = React.useState<string>("")
React.useEffect(() => {
if (dateRange?.from) {
setFromDate(format(dateRange.from, "yyyy-MM-dd"))
}
if (dateRange?.to) {
setToDate(format(dateRange.to, "yyyy-MM-dd"))
}
}, [dateRange])
const handleFromDateChange = (value: string) => {
setFromDate(value)
const from = value ? new Date(value) : undefined
const to = toDate ? new Date(toDate) : dateRange?.to
if (from && to && from > to) {
// If from date is after to date, adjust to date
onDateRangeChange?.({ from, to: from })
setToDate(value)
} else {
onDateRangeChange?.({ from, to })
}
}
const handleToDateChange = (value: string) => {
setToDate(value)
const from = fromDate ? new Date(fromDate) : dateRange?.from
const to = value ? new Date(value) : undefined
if (from && to && from > to) {
// If to date is before from date, adjust from date
onDateRangeChange?.({ from: to, to })
setFromDate(value)
} else {
onDateRangeChange?.({ from, to })
}
}
return (
<div className={cn("flex items-center gap-2", className)}>
<div className="flex items-center gap-2">
<Label htmlFor="from-date" className="text-sm whitespace-nowrap">From:</Label>
<Input
id="from-date"
type="date"
value={fromDate}
onChange={(e) => handleFromDateChange(e.target.value)}
className="w-32"
/>
</div>
<div className="flex items-center gap-2">
<Label htmlFor="to-date" className="text-sm whitespace-nowrap">To:</Label>
<Input
id="to-date"
type="date"
value={toDate}
onChange={(e) => handleToDateChange(e.target.value)}
className="w-32"
/>
</div>
</div>
)
}
// Date Range Display Component
export function DateRangeDisplay({ dateRange }: { dateRange?: DateRange }) {
if (!dateRange?.from) return null
const daysDiff = dateRange.to
? Math.ceil((dateRange.to.getTime() - dateRange.from.getTime()) / (1000 * 60 * 60 * 24)) + 1
: 1
return (
<div className="flex items-center gap-2">
<Badge variant="secondary" className="text-xs">
{daysDiff} day{daysDiff !== 1 ? 's' : ''}
</Badge>
<span className="text-sm text-muted-foreground">
{format(dateRange.from, "MMM dd")}
{dateRange.to && !isSameDay(dateRange.from, dateRange.to) && (
<> - {format(dateRange.to, "MMM dd, yyyy")}</>
)}
</span>
</div>
)
}

View File

@@ -1,8 +1,3 @@
/**
* Business motivation quotes for the dashboard
* Collection of quotes from successful entrepreneurs and business leaders
*/
export interface Quote { export interface Quote {
text: string; text: string;
author: string; author: string;
@@ -50,6 +45,38 @@ export const businessQuotes: Quote[] = [
{ text: "If you want to achieve greatness stop asking for permission.", author: "Anonymous" }, { text: "If you want to achieve greatness stop asking for permission.", author: "Anonymous" },
{ text: "Things work out best for those who make the best of how things work out.", author: "John Wooden" }, { text: "Things work out best for those who make the best of how things work out.", author: "John Wooden" },
{ text: "The most valuable businesses of coming decades will be built by entrepreneurs who seek to empower people rather than try to make them obsolete.", author: "Peter Thiel" }, { text: "The most valuable businesses of coming decades will be built by entrepreneurs who seek to empower people rather than try to make them obsolete.", author: "Peter Thiel" },
// Additional quotes - Vision and leadership
{ text: "Leadership is the capacity to translate vision into reality.", author: "Warren Bennis" },
{ text: "A goal without a plan is just a wish.", author: "Antoine de Saint-Exupéry" },
{ text: "Good business leaders create a vision, articulate the vision, passionately own the vision, and relentlessly drive it to completion.", author: "Jack Welch" },
// Additional quotes - Risk, failure, and learning
{ text: "Fail often so you can succeed sooner.", author: "Tom Kelley" },
{ text: "Dont worry about failure; you only have to be right once.", author: "Drew Houston" },
{ text: "In the middle of difficulty lies opportunity.", author: "Albert Einstein" },
{ text: "Risk more than others think is safe. Dream more than others think is practical.", author: "Howard Schultz" },
// Additional quotes - Action and hustle
{ text: "Ideas are easy. Implementation is hard.", author: "Guy Kawasaki" },
{ text: "Success usually comes to those who are too busy to be looking for it.", author: "Henry David Thoreau" },
{ text: "Done is better than perfect.", author: "Sheryl Sandberg" },
{ text: "Action is the foundational key to all success.", author: "Pablo Picasso" },
// Additional quotes - Customer and product
{ text: "People don't buy what you do; they buy why you do it.", author: "Simon Sinek" },
{ text: "The customer is the most important part of the production line.", author: "W. Edwards Deming" },
{ text: "Make something people want and sell that, or be someone people need and sell yourself.", author: "Naval Ravikant" },
// Additional quotes - Resilience and mindset
{ text: "Success is walking from failure to failure with no loss of enthusiasm.", author: "Winston Churchill" },
{ text: "Whether you think you can or you think you cant, youre right.", author: "Henry Ford" },
{ text: "Strength and growth come only through continuous effort and struggle.", author: "Napoleon Hill" },
{ text: "Believe you can and you're halfway there.", author: "Theodore Roosevelt" },
// Additional quotes - Money and value
{ text: "Try not to become a man of success, but rather try to become a man of value.", author: "Albert Einstein" },
{ text: "Price is what you pay. Value is what you get.", author: "Warren Buffett" },
]; ];
// For backward compatibility with existing code // For backward compatibility with existing code