REMINDERS QUICK REFERENCE - nself-org/nchat GitHub Wiki
Reminders System - Quick Reference Card
Version: 1.0.0 | Status: Production Ready ✅
🚀 Quick Start (30 seconds)
// 1. Add to your app layout
import { ReminderNotificationContainer } from '@/components/reminders'
;<ReminderNotificationContainer userId={user.id} />
// 2. Use in any component
import { useReminders } from '@/lib/reminders/use-reminders'
const { createReminder, reminders } = useReminders({ userId: user.id })
📦 Import Cheat Sheet
// Components
import {
RemindersList, // Full list with filters
SetReminderModal, // Create/Edit modal
ReminderItem, // Single reminder card
ReminderNotification, // Notification UI
QuickRemind, // Quick time picker
ReminderTimePicker, // Date/time picker
} from '@/components/reminders'
// Hooks
import {
useReminders, // Main hook (full API)
useChannelReminders, // Channel-specific
useRemindersCount, // Count only
useMessageReminder, // Message reminder check
} from '@/lib/reminders/use-reminders'
// Store
import { useReminderStore } from '@/lib/reminders/reminder-store'
// Types
import type { Reminder, ReminderDraft } from '@/graphql/reminders'
🎯 Common Use Cases
1. Message Reminder (One-liner)
const { setReminderForMessage } = useReminders({ userId: user.id })
// Set reminder for 1 hour from now
await setReminderForMessage({
messageId: msg.id,
remindAt: new Date(Date.now() + 3600000),
timezone: 'America/New_York',
})
2. Custom Reminder
const { createReminder } = useReminders({ userId: user.id })
await createReminder({
content: 'Call John about the project',
note: 'Discuss timeline',
remindAt: new Date('2026-02-15T14:00:00'),
timezone: 'America/New_York',
type: 'custom',
isRecurring: false,
})
3. Recurring Reminder (Daily Standup)
await createReminder({
content: 'Daily standup',
remindAt: tomorrow9am,
timezone: 'UTC',
type: 'custom',
isRecurring: true,
recurrenceRule: {
frequency: 'daily',
interval: 1,
daysOfWeek: [1, 2, 3, 4, 5], // Mon-Fri
},
})
4. Quick Remind Menu
<QuickRemind messageId={msg.id} channelId={channel.id} messageContent={msg.content} />
5. Full Reminders List
<RemindersList userId={user.id} showFilters showSearch onEdit={(r) => openEditModal(r)} />
🔧 Hook API Reference
useReminders()
const {
// Data
reminders, // All reminders
upcomingReminders, // Pending only
completedReminders, // Completed/dismissed
dueReminders, // Currently due
pendingCount, // Count of pending
nextReminder, // Next upcoming
// Loading states
isLoading,
isCreating,
isUpdating,
isDeleting,
// CRUD
createReminder, // Create new
updateReminder, // Update existing
deleteReminder, // Delete by ID
completeReminder, // Mark complete
snoozeReminder, // Snooze for duration
bulkComplete, // Complete multiple
bulkDelete, // Delete multiple
// Message-specific
setReminderForMessage, // Quick message reminder
hasReminderForMessage, // Check if exists
getReminderForMessage, // Get by message ID
// UI helpers
openReminderModal, // Open creation modal
closeReminderModal, // Close modal
} = useReminders({ userId: user.id })
🎨 Component Props
SetReminderModal
<SetReminderModal
open={boolean}
onOpenChange={(open) => {}}
userId={string}
messageId={string} // Optional: for message reminders
channelId={string} // Optional: context
initialContent={string} // Optional: pre-fill
editingReminder={reminder} // Optional: edit mode
onSuccess={(reminder) => {}}
onCancel={() => {}}
/>
RemindersList
<RemindersList
userId={string}
channelId={string} // Optional: filter by channel
onEdit={(reminder) => {}}
onCreateNew={() => {}}
showFilters={true}
showSearch={true}
showTabs={true}
maxHeight="600px"
className="custom-class"
/>
📊 Quick Time Presets
// Built-in presets
const presets = {
'20min': Date.now() + 20 * 60 * 1000,
'1hour': Date.now() + 60 * 60 * 1000,
'3hours': Date.now() + 3 * 60 * 60 * 1000,
'tomorrow': /* tomorrow 9am */,
'nextWeek': /* next Monday 9am */,
}
// Use in QuickRemind component automatically
🔔 Notification Types
// In-app notification (automatic)
;<ReminderNotificationContainer userId={user.id} />
// Desktop notification (requires permission)
const { requestDesktopPermission } = useNotifications()
await requestDesktopPermission()
// Email notification (configure in user settings)
// Handled by backend automatically
🗄️ GraphQL Operations
Queries
# Get all reminders
query GetReminders($userId: uuid!) {
nchat_reminders(where: { user_id: { _eq: $userId } }) {
...ReminderFragment
}
}
# Get due reminders
query GetDueReminders($userId: uuid!, $now: timestamptz!) {
nchat_reminders(
where: { user_id: { _eq: $userId }, status: { _eq: "pending" }, remind_at: { _lte: $now } }
) {
...ReminderFragment
}
}
Mutations
# Create reminder
mutation CreateReminder($userId: uuid!, $content: String!, $remindAt: timestamptz!) {
insert_nchat_reminders_one(
object: { user_id: $userId, content: $content, remind_at: $remindAt }
) {
...ReminderFragment
}
}
# Complete reminder
mutation CompleteReminder($id: uuid!) {
update_nchat_reminders_by_pk(
pk_columns: { id: $id }
_set: { status: "completed", completed_at: "now()" }
) {
...ReminderFragment
}
}
🌐 REST API
# Get reminders
GET /api/reminders?status=pending&limit=50
# Create reminder
POST /api/reminders
{
"content": "Review PR",
"remindAt": "2026-02-15T14:00:00Z",
"timezone": "America/New_York"
}
# Complete reminder
POST /api/reminders
{
"action": "complete",
"id": "uuid"
}
# Snooze reminder
POST /api/reminders
{
"action": "snooze",
"id": "uuid",
"snoozeDuration": 3600000
}
# Update reminder
PUT /api/reminders
{
"id": "uuid",
"content": "Updated text",
"remindAt": "2026-02-16T10:00:00Z"
}
# Delete reminder
DELETE /api/reminders?id=uuid
🎯 Status Values
type ReminderStatus = 'pending' | 'completed' | 'dismissed' | 'snoozed'
type ReminderType = 'message' | 'custom' | 'followup'
type RecurrenceFrequency = 'daily' | 'weekly' | 'monthly' | 'yearly'
🔍 Filtering Examples
const { setFilter } = useReminderStore()
// Filter by status
setFilter({ status: 'pending' })
// Filter by type
setFilter({ type: 'message' })
// Filter by channel
setFilter({ channelId: 'channel-uuid' })
// Combined filters
setFilter({
status: 'pending',
type: 'message',
channelId: 'channel-uuid',
})
// Reset filters
setFilter({
status: 'all',
type: 'all',
channelId: undefined,
})
⚡ Performance Tips
- Use Subscriptions for real-time updates (already configured)
- Pagination: Use
limitandoffsetfor large lists - Memoization: Components use
useMemointernally - Lazy Load: Modal loads only when opened
- Batch Operations: Use
bulkComplete/bulkDeletefor multiple items
🐛 Debugging
// Check feature flag
const isEnabled = useFeatureEnabled(FEATURES.REMINDERS)
// View store state
const state = useReminderStore.getState()
console.log('Reminders:', state.reminders)
console.log('Due:', state.dueReminders)
console.log('Filter:', state.filter)
// Test notification
const { showNotification } = useReminderStore()
showNotification('reminder-id')
// Force refetch
const { fetchReminders } = useReminders({ userId: user.id })
await fetchReminders()
📱 Mobile/Desktop Compatibility
// Capacitor (iOS/Android)
import { Plugins } from '@capacitor/core'
const { LocalNotifications } = Plugins
// Electron (Desktop)
if (window.electron) {
window.electron.notification.show(...)
}
// Both handled automatically by ReminderNotificationContainer
🔐 Permissions
// Desktop notifications
const { requestDesktopPermission } = useNotifications()
if (Notification.permission === 'default') {
await requestDesktopPermission()
}
// User can only access their own reminders
// Enforced by Hasura permissions (user_id = X-Hasura-User-Id)
✅ Pre-flight Checklist
Before using reminders:
- [ ] Feature flag enabled:
FEATURES.REMINDERS - [ ] Database table exists:
nchat_reminders - [ ] Hasura permissions configured
- [ ] GraphQL endpoint accessible
- [ ] User authenticated
📚 More Resources
- Full Documentation:
/docs/Reminders-System.md - Component Guide:
/src/components/reminders/README.md - Implementation:
/REMINDERS-IMPLEMENTATION.md - GraphQL Schema:
/src/graphql/reminders.ts - API Route:
/src/app/api/reminders/route.ts
🆘 Common Issues
Reminder not showing?
// Check if due
const dueReminders = useReminderStore((s) => s.dueReminders)
// Force check
const { checkDueReminders } = useReminders({ userId })
checkDueReminders()
Desktop notification not working?
// Check permission
console.log(Notification.permission) // Should be "granted"
// Request permission
await requestDesktopPermission()
Timezone issues?
// Use user's timezone
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone
// Or specify
const tz = 'America/New_York'
💡 Pro Tips
- Combine with Message Actions: Add to message dropdown menu
- Keyboard Shortcuts: Use
Cmd+Shift+Rto open modal (if configured) - Default Times: Most users prefer 1 hour, tomorrow 9am, next week
- Batch Creating: Use CSV import for bulk reminders (custom implementation)
- Analytics: Track reminder completion rate for insights
Print this page and keep it handy! 📄
Last updated: February 1, 2026