Function bodies 234 total
POST function · typescript · L6-L98 (93 LOC)src/app/api/admin/invite/route.ts
export async function POST(request: Request) {
const body = await request.json()
const { email, fullName, phone, groupId, roleInGroup, systemRole } = body
if (!email || !fullName) {
return NextResponse.json(
{ success: false, error: 'Email and full name are required' },
{ status: 400 }
)
}
// Authenticate the calling user via cookie
const cookieStore = await cookies()
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll() {
// Read-only in API route
},
},
}
)
const { data: { user } } = await supabase.auth.getUser()
if (!user) {
return NextResponse.json(
{ success: false, error: 'Not authenticated' },
{ status: 401 }
)
}
const { data: profile } = await supabase
.from('profiles')
.select('role')
.eq('id'AdminGroupsPage function · typescript · L15-L143 (129 LOC)src/app/(app)/admin/groups/page.tsx
export default function AdminGroupsPage() {
const supabase = createClient()
const [name, setName] = useState('')
const [description, setDescription] = useState('')
const [geography, setGeography] = useState('US')
const [cadence, setCadence] = useState('weekly')
const { data: groups } = useSWR('admin-groups', async () => {
const { data } = await supabase
.from('groups')
.select('*, group_members(id, user_id, role_in_group, profiles(full_name))')
.order('name')
return data || []
})
async function handleCreate() {
await supabase.from('groups').insert({ name, description, geography, meeting_cadence: cadence })
setName('')
setDescription('')
mutate('admin-groups')
}
async function addMember(groupId: string, userId: string, role: string = 'member') {
await supabase.from('group_members').insert({ group_id: groupId, user_id: userId, role_in_group: role })
mutate('admin-groups')
}
async function removeMember(membershihandleCreate function · typescript · L30-L35 (6 LOC)src/app/(app)/admin/groups/page.tsx
async function handleCreate() {
await supabase.from('groups').insert({ name, description, geography, meeting_cadence: cadence })
setName('')
setDescription('')
mutate('admin-groups')
}addMember function · typescript · L37-L40 (4 LOC)src/app/(app)/admin/groups/page.tsx
async function addMember(groupId: string, userId: string, role: string = 'member') {
await supabase.from('group_members').insert({ group_id: groupId, user_id: userId, role_in_group: role })
mutate('admin-groups')
}removeMember function · typescript · L42-L45 (4 LOC)src/app/(app)/admin/groups/page.tsx
async function removeMember(membershipId: string) {
await supabase.from('group_members').delete().eq('id', membershipId)
mutate('admin-groups')
}AdminLayout function · typescript · L4-L23 (20 LOC)src/app/(app)/admin/layout.tsx
export default async function AdminLayout({ children }: { children: React.ReactNode }) {
const supabase = await createClient()
const { data: { user } } = await supabase.auth.getUser()
if (!user) {
redirect('/login')
}
const { data: profile } = await supabase
.from('profiles')
.select('role')
.eq('id', user.id)
.single()
if (profile?.role !== 'system_admin') {
redirect('/dashboard')
}
return <>{children}</>
}AdminQuartersPage function · typescript · L14-L106 (93 LOC)src/app/(app)/admin/quarters/page.tsx
export default function AdminQuartersPage() {
const supabase = createClient()
const [label, setLabel] = useState('')
const [startDate, setStartDate] = useState('')
const [endDate, setEndDate] = useState('')
const { data: quarters } = useSWR('admin-quarters', async () => {
const { data } = await supabase.from('quarters').select('*').order('start_date', { ascending: false })
return data || []
})
async function handleCreate() {
await supabase.from('quarters').insert({ label, start_date: startDate, end_date: endDate })
setLabel('')
setStartDate('')
setEndDate('')
mutate('admin-quarters')
}
async function setCurrentQuarter(id: string) {
await supabase.from('quarters').update({ is_current: true }).eq('id', id)
mutate('admin-quarters')
}
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<CalendarDays className="h-6 w-6 text-If a scraper extracted this row, it came from Repobility (https://repobility.com)
handleCreate function · typescript · L25-L31 (7 LOC)src/app/(app)/admin/quarters/page.tsx
async function handleCreate() {
await supabase.from('quarters').insert({ label, start_date: startDate, end_date: endDate })
setLabel('')
setStartDate('')
setEndDate('')
mutate('admin-quarters')
}setCurrentQuarter function · typescript · L33-L36 (4 LOC)src/app/(app)/admin/quarters/page.tsx
async function setCurrentQuarter(id: string) {
await supabase.from('quarters').update({ is_current: true }).eq('id', id)
mutate('admin-quarters')
}InviteDialog function · typescript · L42-L147 (106 LOC)src/app/(app)/admin/users/page.tsx
function InviteDialog({ groups }: { groups: GroupOption[] }) {
const [open, setOpen] = useState(false)
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const [form, setForm] = useState({
fullName: '',
email: '',
phone: '',
groupId: '',
roleInGroup: 'member',
systemRole: 'team_member',
})
function updateField(field: string, value: string) {
setForm((prev) => ({ ...prev, [field]: value }))
}
async function handleInvite() {
setLoading(true)
setError('')
try {
const res = await fetch('/api/admin/invite', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(form),
})
const data = await res.json()
if (!data.success) {
setError(data.error || 'Failed to send invite')
} else {
setForm({ fullName: '', email: '', phone: '', groupId: '', roleInGroup: 'member', systemRole: 'team_member' })
setOpupdateField function · typescript · L55-L57 (3 LOC)src/app/(app)/admin/users/page.tsx
function updateField(field: string, value: string) {
setForm((prev) => ({ ...prev, [field]: value }))
}handleInvite function · typescript · L59-L80 (22 LOC)src/app/(app)/admin/users/page.tsx
async function handleInvite() {
setLoading(true)
setError('')
try {
const res = await fetch('/api/admin/invite', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(form),
})
const data = await res.json()
if (!data.success) {
setError(data.error || 'Failed to send invite')
} else {
setForm({ fullName: '', email: '', phone: '', groupId: '', roleInGroup: 'member', systemRole: 'team_member' })
setOpen(false)
mutate('admin-users')
}
} catch {
setError('Network error. Please try again.')
}
setLoading(false)
}EditUserDialog function · typescript · L151-L296 (146 LOC)src/app/(app)/admin/users/page.tsx
function EditUserDialog({
user,
groups,
open,
onOpenChange,
}: {
user: UserProfile
groups: GroupOption[]
open: boolean
onOpenChange: (open: boolean) => void
}) {
const supabase = createClient()
const [loading, setLoading] = useState(false)
const [form, setForm] = useState({
fullName: user.full_name,
phone: user.phone || '',
geography: user.geography || '',
role: user.role,
isActive: user.is_active,
})
function updateField(field: string, value: string | boolean) {
setForm((prev) => ({ ...prev, [field]: value }))
}
async function handleSave() {
setLoading(true)
await supabase
.from('profiles')
.update({
full_name: form.fullName,
phone: form.phone || null,
geography: form.geography || null,
role: form.role,
is_active: form.isActive,
})
.eq('id', user.id)
setLoading(false)
onOpenChange(false)
mutate('admin-users')
}
async function addToGroup(groupupdateField function · typescript · L172-L174 (3 LOC)src/app/(app)/admin/users/page.tsx
function updateField(field: string, value: string | boolean) {
setForm((prev) => ({ ...prev, [field]: value }))
}handleSave function · typescript · L176-L191 (16 LOC)src/app/(app)/admin/users/page.tsx
async function handleSave() {
setLoading(true)
await supabase
.from('profiles')
.update({
full_name: form.fullName,
phone: form.phone || null,
geography: form.geography || null,
role: form.role,
is_active: form.isActive,
})
.eq('id', user.id)
setLoading(false)
onOpenChange(false)
mutate('admin-users')
}Repobility · MCP-ready · https://repobility.com
addToGroup function · typescript · L193-L200 (8 LOC)src/app/(app)/admin/users/page.tsx
async function addToGroup(groupId: string) {
await supabase.from('group_members').insert({
group_id: groupId,
user_id: user.id,
role_in_group: 'member',
})
mutate('admin-users')
}removeFromGroup function · typescript · L202-L205 (4 LOC)src/app/(app)/admin/users/page.tsx
async function removeFromGroup(membershipId: string) {
await supabase.from('group_members').delete().eq('id', membershipId)
mutate('admin-users')
}AdminUsersPage function · typescript · L300-L391 (92 LOC)src/app/(app)/admin/users/page.tsx
export default function AdminUsersPage() {
const supabase = createClient()
const [editingUser, setEditingUser] = useState<UserProfile | null>(null)
const { data: users } = useSWR('admin-users', async () => {
const { data } = await supabase
.from('profiles')
.select('*, group_members(id, group_id, role_in_group, groups(id, name))')
.order('full_name')
return (data || []) as UserProfile[]
})
const { data: groups } = useSWR('all-groups', async () => {
const { data } = await supabase
.from('groups')
.select('id, name')
.order('name')
return (data || []) as GroupOption[]
})
const roleLabels: Record<string, string> = {
team_member: 'Team Member',
group_admin: 'Group Admin',
executive: 'Executive',
system_admin: 'System Admin',
}
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<Users className="DashboardPage function · typescript · L16-L289 (274 LOC)src/app/(app)/dashboard/page.tsx
export default function DashboardPage() {
const supabase = createClient()
const { user } = useUser()
const groups = user?.group_members?.map((gm: any) => gm.groups) || []
const { data: quarters } = useQuarters()
const [selectedQuarter, setSelectedQuarter] = useState<string | null>(null)
const [selectedGroupId, setSelectedGroupId] = useState<string | null>(null)
const [top10DialogOpen, setTop10DialogOpen] = useState(false)
// Compute current week Monday (local time, avoid UTC shift from toISOString)
const currentWeekMonday = (() => {
const today = new Date()
const monday = new Date(today)
monday.setDate(today.getDate() - ((today.getDay() + 6) % 7))
const y = monday.getFullYear()
const m = String(monday.getMonth() + 1).padStart(2, '0')
const d = String(monday.getDate()).padStart(2, '0')
return `${y}-${m}-${d}`
})()
useEffect(() => {
if (quarters && !selectedQuarter) {
const current = quarters.find((q: any) => q.is_current)
FocusPage function · typescript · L16-L192 (177 LOC)src/app/(app)/groups/[groupId]/focus/page.tsx
export default function FocusPage() {
const params = useParams()
const groupId = params.groupId as string
const { user } = useUser()
const [weekIndex, setWeekIndex] = useState(0)
const [selectedMemberId, setSelectedMemberId] = useState<string | null>(null)
// Set default member to current user
useEffect(() => {
if (user && !selectedMemberId) {
setSelectedMemberId(user.id)
}
}, [user, selectedMemberId])
const { data: weekDates } = useWeekDates(user?.id || null, groupId)
const currentWeekDate = weekDates?.[weekIndex]?.week_date || null
// Compute isCurrentWeek from date instead of DB flag
const isCurrentWeek = (() => {
if (!currentWeekDate) return false
const today = new Date()
const monday = new Date(today)
monday.setDate(today.getDate() - ((today.getDay() + 6) % 7))
const thisMonday = `${monday.getFullYear()}-${String(monday.getMonth() + 1).padStart(2, '0')}-${String(monday.getDate()).padStart(2, '0')}`
return currentWeekhandleStartNewWeek function · typescript · L67-L85 (19 LOC)src/app/(app)/groups/[groupId]/focus/page.tsx
async function handleStartNewWeek() {
if (!user) return
const today = new Date()
const monday = new Date(today)
monday.setDate(today.getDate() - ((today.getDay() + 6) % 7))
const weekDate = `${monday.getFullYear()}-${String(monday.getMonth() + 1).padStart(2, '0')}-${String(monday.getDate()).padStart(2, '0')}`
await supabase.rpc('start_new_week', {
p_user_id: user.id,
p_group_id: groupId,
p_new_week_date: weekDate,
})
mutate(`week-dates-${user.id}-${groupId}`)
mutate(`focus-${user.id}-${groupId}-${weekDate}`)
mutate(`group-focus-${groupId}-${weekDate}`)
setWeekIndex(0)
}handleCreateFirstSnapshot function · typescript · L87-L104 (18 LOC)src/app/(app)/groups/[groupId]/focus/page.tsx
async function handleCreateFirstSnapshot() {
if (!user) return
const today = new Date()
const monday = new Date(today)
monday.setDate(today.getDate() - ((today.getDay() + 6) % 7))
const weekDate = `${monday.getFullYear()}-${String(monday.getMonth() + 1).padStart(2, '0')}-${String(monday.getDate()).padStart(2, '0')}`
await supabase.from('focus_snapshots').insert({
user_id: user.id,
group_id: groupId,
week_date: weekDate,
is_current: true,
})
mutate(`week-dates-${user.id}-${groupId}`)
setWeekIndex(0)
}IssuesPage function · typescript · L22-L244 (223 LOC)src/app/(app)/groups/[groupId]/issues/page.tsx
export default function IssuesPage() {
const params = useParams()
const groupId = params.groupId as string
const { user } = useUser()
const supabase = createClient()
const [raisedByFilter, setRaisedByFilter] = useState<string | null>(null)
const [priorityFilter, setPriorityFilter] = useState<string | null>(null)
const [statusFilter, setStatusFilter] = useState<string | null>(null)
const [selectedIssue, setSelectedIssue] = useState<any>(null)
const [detailOpen, setDetailOpen] = useState(false)
const [viewMode, setViewMode] = useViewPreference('eos-issues-view', 'table')
const { data: issues, isLoading } = useSWR(`issues-${groupId}`, async () => {
const { data } = await supabase
.from('issues')
.select('*, raised_by_user:profiles!raised_by(id, full_name), assigned_to:profiles!assigned_to_id(full_name)')
.eq('group_id', groupId)
.eq('is_archived', false)
.order('created_at', { ascending: false })
return data || []
}, { refresAbout: code-quality intelligence by Repobility · https://repobility.com
handleRowClick function · typescript · L68-L71 (4 LOC)src/app/(app)/groups/[groupId]/issues/page.tsx
function handleRowClick(issue: any) {
setSelectedIssue(issue)
setDetailOpen(true)
}MeetingViewPage function · typescript · L22-L196 (175 LOC)src/app/(app)/groups/[groupId]/meetings/[meetingId]/page.tsx
export default function MeetingViewPage() {
const params = useParams()
const router = useRouter()
const groupId = params.groupId as string
const meetingId = params.meetingId as string
const supabase = createClient()
const [activeStep, setActiveStep] = useState('checkins')
const { data: meeting, isLoading } = useSWR(`meeting-${meetingId}`, async () => {
const { data, error } = await supabase
.from('meetings')
.select('*, meeting_attendees(*, user:profiles!user_id(id, full_name))')
.eq('id', meetingId)
.single()
if (error) throw error
return data
})
const { data: quarters } = useQuarters()
const currentQuarter = quarters?.find((q: any) => q.is_current)
const { data: rocks } = useRocks(groupId, currentQuarter?.id || null)
// Convert meeting date to the Monday of that week (focus snapshots are always Monday-anchored)
const meetingWeekMonday = meeting?.meeting_date
? (() => {
const d = new Date(meeting.meeting_date updateCheckin function · typescript · L53-L56 (4 LOC)src/app/(app)/groups/[groupId]/meetings/[meetingId]/page.tsx
async function updateCheckin(attendeeId: string, note: string) {
await supabase.from('meeting_attendees').update({ checkin_note: note }).eq('id', attendeeId)
mutate(`meeting-${meetingId}`)
}updateNotes function · typescript · L58-L61 (4 LOC)src/app/(app)/groups/[groupId]/meetings/[meetingId]/page.tsx
async function updateNotes(notes: string) {
await supabase.from('meetings').update({ notes }).eq('id', meetingId)
mutate(`meeting-${meetingId}`)
}MeetingsPage function · typescript · L14-L86 (73 LOC)src/app/(app)/groups/[groupId]/meetings/page.tsx
export default function MeetingsPage() {
const params = useParams()
const groupId = params.groupId as string
const supabase = createClient()
const { data: meetings, isLoading } = useSWR(`meetings-${groupId}`, async () => {
const { data, error } = await supabase
.from('meetings')
.select('*, meeting_attendees(id, score)')
.eq('group_id', groupId)
.order('meeting_date', { ascending: false })
if (error) throw error
return data
})
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<Calendar className="h-6 w-6 text-primary" />
<h1 className="text-2xl font-semibold">Meetings</h1>
</div>
<CreateMeetingButton groupId={groupId} />
</div>
{isLoading ? (
<div className="space-y-3 animate-stagger">
<TableSkeleton rows={4} />
</div>
) : meetings?.length === 0 ? (
<ERocksPage function · typescript · L23-L216 (194 LOC)src/app/(app)/groups/[groupId]/rocks/page.tsx
export default function RocksPage() {
const params = useParams()
const groupId = params.groupId as string
const searchParams = useSearchParams()
const router = useRouter()
const { user } = useUser()
const { data: groupMembers } = useSWR(
`group-members-${groupId}`,
async () => {
const supabase = createClient()
const { data } = await supabase
.from('group_members')
.select('user_id, profiles!user_id(id, full_name)')
.eq('group_id', groupId)
return data || []
}
)
const initialStatus = searchParams.get('status')
const initialOwner = searchParams.get('owner')
const [statusFilter, setStatusFilter] = useState<string | null>(initialStatus)
const [ownerFilter, setOwnerFilter] = useState<string | null>(initialOwner || 'self')
// Resolve 'self' to actual user ID once user loads
useEffect(() => {
if (ownerFilter === 'self' && user?.id) {
setOwnerFilter(user.id)
}
}, [user, ownerFilter])
const { datRockDetailPage function · typescript · L12-L95 (84 LOC)src/app/(app)/groups/[groupId]/rocks/[rockId]/page.tsx
export default function RockDetailPage() {
const params = useParams()
const router = useRouter()
const groupId = params.groupId as string
const rockId = params.rockId as string
const supabase = createClient()
const { data: rock, isLoading } = useSWR(`rock-${rockId}`, async () => {
const { data, error } = await supabase
.from('rocks')
.select('*, owner:profiles!owner_id(id, full_name), quarter:quarters!quarter_id(id, label, is_current)')
.eq('id', rockId)
.single()
if (error) throw error
return data
})
async function updateRock(field: string, value: any) {
await supabase.from('rocks').update({ [field]: value }).eq('id', rockId)
mutate(`rock-${rockId}`)
mutate(`rocks-${groupId}-${rock?.quarter_id}`)
}
if (isLoading || !rock) {
return <p className="text-muted-foreground">Loading rock...</p>
}
const isCurrentQuarter = rock.quarter?.is_current ?? false
const readOnly = !isCurrentQuarter
return (
<div clupdateRock function · typescript · L29-L33 (5 LOC)src/app/(app)/groups/[groupId]/rocks/[rockId]/page.tsx
async function updateRock(field: string, value: any) {
await supabase.from('rocks').update({ [field]: value }).eq('id', rockId)
mutate(`rock-${rockId}`)
mutate(`rocks-${groupId}-${rock?.quarter_id}`)
}Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
CampaignsPage function · typescript · L21-L198 (178 LOC)src/app/(app)/groups/[groupId]/scorecard/campaigns/page.tsx
export default function CampaignsPage() {
const params = useParams()
const groupId = params.groupId as string
const supabase = createClient()
const { user } = useUser()
const { data: campaigns, isLoading } = useCampaigns(groupId)
const { data: settings } = useScorecardSettings(groupId)
const [showArchived, setShowArchived] = useState(false)
const [createOpen, setCreateOpen] = useState(false)
const [selectedCampaign, setSelectedCampaign] = useState<string | null>(null)
const [weekEndings, setWeekEndings] = useState<string[]>([])
const activeCampaigns = campaigns?.filter((c: any) => c.status === 'active') || []
const archivedCampaigns = campaigns?.filter((c: any) => c.status === 'archived') || []
const displayCampaigns = showArchived ? archivedCampaigns : activeCampaigns
const handleArchive = useCallback(async (campaignId: string) => {
await supabase
.from('campaigns')
.update({ status: 'archived', archived_at: new Date().toISOString() })
ScorecardDashboardPage function · typescript · L24-L220 (197 LOC)src/app/(app)/groups/[groupId]/scorecard/dashboard/page.tsx
export default function ScorecardDashboardPage() {
const params = useParams()
const groupId = params.groupId as string
const quarterLabel = getCurrentQuarterLabel()
const [weekEndings, setWeekEndings] = useState<string[]>([])
const [selectedSection, setSelectedSection] = useState<string>('all')
const { data: settings } = useScorecardSettings(groupId)
const { data: template, isLoading: templateLoading } = useScorecardTemplate(groupId)
const { data: entries } = useScorecardEntries(groupId, weekEndings)
const { data: goals } = useScorecardGoals(groupId, quarterLabel)
const { data: campaigns } = useCampaigns(groupId)
const { data: metrics } = useCampaignMetrics(groupId)
// Build lookup maps
const entryMap = useMemo(() => {
const map = new Map<string, any>()
entries?.forEach((e: any) => map.set(`${e.measure_id}-${e.week_ending}`, e))
return map
}, [entries])
const goalMap = useMemo(() => {
const map = new Map<string, number>()
goals?.forScorecardPage function · typescript · L23-L162 (140 LOC)src/app/(app)/groups/[groupId]/scorecard/page.tsx
export default function ScorecardPage() {
const params = useParams()
const groupId = params.groupId as string
const { user } = useUser()
// Time controls
const [weekEndings, setWeekEndings] = useState<string[]>([])
const quarterLabel = getCurrentQuarterLabel()
// Data hooks
const { data: settings } = useScorecardSettings(groupId)
const { data: template, isLoading: templateLoading } = useScorecardTemplate(groupId)
const { data: entries, isLoading: entriesLoading } = useScorecardEntries(groupId, weekEndings)
const { data: goals } = useScorecardGoals(groupId, quarterLabel)
// Goal editor state
const [goalEditor, setGoalEditor] = useState<{
open: boolean
goalId: string | null
measureId: string
measureName: string
dataType: string
currentValue: number | null
}>({ open: false, goalId: null, measureId: '', measureName: '', dataType: 'count', currentValue: null })
// Detail panel state
const [detailPanel, setDetailPanel] = useState<{
ScorecardSettingsPage function · typescript · L47-L305 (259 LOC)src/app/(app)/groups/[groupId]/scorecard/settings/page.tsx
export default function ScorecardSettingsPage() {
const params = useParams()
const groupId = params.groupId as string
const { user } = useUser()
const supabase = createClient()
const { data: settings } = useScorecardSettings(groupId)
const { data: metricsRaw } = useCampaignMetrics(groupId)
const weekEndingDay = settings?.week_ending_day || 'friday'
const [saving, setSaving] = useState(false)
// Campaign metrics local state
const [metrics, setMetrics] = useState<MetricRow[] | null>(null)
const displayMetrics: MetricRow[] = metrics ?? (metricsRaw?.map((m: any, i: number) => ({
id: m.id,
metric_key: m.metric_key,
label: m.label,
data_type: m.data_type,
is_required: m.is_required,
display_order: m.display_order ?? i,
})) || [])
// Save week-ending day
const handleWeekEndingChange = useCallback(async (value: string) => {
setSaving(true)
const { error } = await supabase
.from('scorecard_settings')
.upsert(
{ AppLayout function · typescript · L3-L20 (18 LOC)src/app/(app)/layout.tsx
export default function AppLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex h-screen">
<Sidebar />
<div className="flex-1 flex flex-col overflow-hidden">
<header className="lg:hidden flex items-center gap-3 border-b bg-sidebar px-4 py-3">
<MobileSidebar />
<span className="font-semibold text-primary font-[family-name:var(--font-montserrat)]">
EOS L10
</span>
</header>
<main className="flex-1 overflow-y-auto bg-muted p-4 lg:p-6">
{children}
</main>
</div>
</div>
)
}RockIdeasPage function · typescript · L15-L165 (151 LOC)src/app/(app)/rock-ideas/page.tsx
export default function RockIdeasPage() {
const supabase = createClient()
const { user } = useUser()
const { data: quarters } = useQuarters()
const [promoteQuarterId, setPromoteQuarterId] = useState<string>('')
const currentQuarter = quarters?.find((q: any) => q.is_current)
if (currentQuarter && !promoteQuarterId) {
setPromoteQuarterId(currentQuarter.id)
}
const groups = user?.group_members?.map((gm: any) => gm.groups) || []
const firstGroupId = groups[0]?.id
const { data: ideas, isLoading } = useSWR('rock-ideas', async () => {
const { data, error } = await supabase
.from('rock_ideas')
.select('*, suggested_owner:profiles!suggested_owner_id(full_name), promoted_to_rock:rocks!promoted_to_rock_id(id, title)')
.order('priority_color', { ascending: true })
.order('created_at', { ascending: false })
if (error) throw error
return data
})
async function promoteIdea(ideaId: string, ownerId: string | null) {
if (!promoteQuapromoteIdea function · typescript · L39-L57 (19 LOC)src/app/(app)/rock-ideas/page.tsx
async function promoteIdea(ideaId: string, ownerId: string | null) {
if (!promoteQuarterId || !ownerId) {
alert('Please select a quarter and ensure the idea has a suggested owner.')
return
}
const { error } = await supabase.rpc('promote_rock_idea', {
p_idea_id: ideaId,
p_quarter_id: promoteQuarterId,
p_owner_id: ownerId,
})
if (error) {
alert('Error promoting idea: ' + error.message)
return
}
mutate('rock-ideas')
}GET function · typescript · L4-L17 (14 LOC)src/app/(auth)/auth/callback/route.ts
export async function GET(request: Request) {
const { searchParams, origin } = new URL(request.url)
const code = searchParams.get('code')
if (code) {
const supabase = await createClient()
const { error } = await supabase.auth.exchangeCodeForSession(code)
if (!error) {
return NextResponse.redirect(`${origin}/dashboard`)
}
}
return NextResponse.redirect(`${origin}/login?error=auth`)
}If a scraper extracted this row, it came from Repobility (https://repobility.com)
LoginForm function · typescript · L21-L43 (23 LOC)src/app/(auth)/login/page.tsx
function LoginForm({ idPrefix, email, setEmail, loading, message, handleLogin }: LoginFormProps) {
return (
<form onSubmit={handleLogin} className="space-y-4">
<div className="space-y-2">
<Label htmlFor={`${idPrefix}-email`}>Email</Label>
<Input
id={`${idPrefix}-email`}
type="email"
placeholder="[email protected]"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<Button type="submit" className="w-full" disabled={loading}>
{loading ? 'Sending...' : 'Send Login Link'}
</Button>
{message && (
<p className="text-sm text-center text-muted-foreground">{message}</p>
)}
</form>
)
}LoginPage function · typescript · L45-L51 (7 LOC)src/app/(auth)/login/page.tsx
export default function LoginPage() {
return (
<Suspense>
<LoginPageContent />
</Suspense>
)
}LoginPageContent function · typescript · L53-L176 (124 LOC)src/app/(auth)/login/page.tsx
function LoginPageContent() {
const [email, setEmail] = useState('')
const [loading, setLoading] = useState(false)
const [message, setMessage] = useState('')
const searchParams = useSearchParams()
const isDeactivated = searchParams.get('deactivated') === 'true'
const supabase = createClient()
async function handleLogin(e: React.FormEvent) {
e.preventDefault()
setLoading(true)
setMessage('')
const { error } = await supabase.auth.signInWithOtp({
email,
options: {
emailRedirectTo: `${window.location.origin}/auth/callback`,
},
})
if (error) {
setMessage(error.message)
} else {
setMessage('Check your email for the login link.')
}
setLoading(false)
}
return (
<div className="flex min-h-screen">
{/* Left panel - VG branding */}
<div className="hidden md:flex md:w-1/2 flex-col items-center justify-center bg-primary px-12 relative overflow-hidden geo-pattern">
<Image
handleLogin function · typescript · L61-L79 (19 LOC)src/app/(auth)/login/page.tsx
async function handleLogin(e: React.FormEvent) {
e.preventDefault()
setLoading(true)
setMessage('')
const { error } = await supabase.auth.signInWithOtp({
email,
options: {
emailRedirectTo: `${window.location.origin}/auth/callback`,
},
})
if (error) {
setMessage(error.message)
} else {
setMessage('Check your email for the login link.')
}
setLoading(false)
}RootLayout function · typescript · L23-L37 (15 LOC)src/app/layout.tsx
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en" suppressHydrationWarning>
<body
className={`${montserrat.variable} ${dmSans.variable} antialiased`}
>
<Providers>{children}</Providers>
</body>
</html>
);
}Home function · typescript · L3-L5 (3 LOC)src/app/page.tsx
export default function Home() {
redirect('/dashboard')
}CreateIssueDialog function · typescript · L17-L70 (54 LOC)src/components/create-issue-dialog.tsx
export function CreateIssueDialog({ groupId }: CreateIssueDialogProps) {
const [open, setOpen] = useState(false)
const [description, setDescription] = useState('')
const [priority, setPriority] = useState('')
const [assignedTo, setAssignedTo] = useState<string | null>(null)
const supabase = createClient()
const { user } = useUser()
async function handleCreate() {
if (!description.trim() || !user) return
await supabase.from('issues').insert({
group_id: groupId,
raised_by: user.id,
description: description.trim(),
priority: priority ? parseInt(priority) : null,
assigned_to_id: assignedTo,
})
setDescription('')
setPriority('')
setAssignedTo(null)
setOpen(false)
mutate(`issues-${groupId}`)
}
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button>New Issue</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Raise handleCreate function · typescript · L25-L41 (17 LOC)src/components/create-issue-dialog.tsx
async function handleCreate() {
if (!description.trim() || !user) return
await supabase.from('issues').insert({
group_id: groupId,
raised_by: user.id,
description: description.trim(),
priority: priority ? parseInt(priority) : null,
assigned_to_id: assignedTo,
})
setDescription('')
setPriority('')
setAssignedTo(null)
setOpen(false)
mutate(`issues-${groupId}`)
}Repobility · MCP-ready · https://repobility.com
CreateMeetingButton function · typescript · L12-L53 (42 LOC)src/components/create-meeting-dialog.tsx
export function CreateMeetingButton({ groupId }: CreateMeetingDialogProps) {
const supabase = createClient()
const router = useRouter()
async function handleStartMeeting() {
const today = new Date().toISOString().split('T')[0]
// Create meeting
const { data: meeting, error } = await supabase
.from('meetings')
.insert({ group_id: groupId, meeting_date: today })
.select()
.single()
if (error || !meeting) {
alert('Error creating meeting: ' + (error?.message || 'Unknown error'))
return
}
// Get group members and add as attendees
const { data: members } = await supabase
.from('group_members')
.select('user_id')
.eq('group_id', groupId)
if (members && members.length > 0) {
await supabase.from('meeting_attendees').insert(
members.map((m: any) => ({
meeting_id: meeting.id,
user_id: m.user_id,
}))
)
}
mutate(`meetings-${groupId}`)
router.phandleStartMeeting function · typescript · L16-L48 (33 LOC)src/components/create-meeting-dialog.tsx
async function handleStartMeeting() {
const today = new Date().toISOString().split('T')[0]
// Create meeting
const { data: meeting, error } = await supabase
.from('meetings')
.insert({ group_id: groupId, meeting_date: today })
.select()
.single()
if (error || !meeting) {
alert('Error creating meeting: ' + (error?.message || 'Unknown error'))
return
}
// Get group members and add as attendees
const { data: members } = await supabase
.from('group_members')
.select('user_id')
.eq('group_id', groupId)
if (members && members.length > 0) {
await supabase.from('meeting_attendees').insert(
members.map((m: any) => ({
meeting_id: meeting.id,
user_id: m.user_id,
}))
)
}
mutate(`meetings-${groupId}`)
router.push(`/groups/${groupId}/meetings/${meeting.id}`)
}CreateRockDialog function · typescript · L18-L101 (84 LOC)src/components/create-rock-dialog.tsx
export function CreateRockDialog({ groupId }: CreateRockDialogProps) {
const [open, setOpen] = useState(false)
const [title, setTitle] = useState('')
const [quarterId, setQuarterId] = useState('')
const [targetDate, setTargetDate] = useState('')
const [notes, setNotes] = useState('')
const supabase = createClient()
const { data: quarters } = useQuarters()
const { user } = useUser()
// Default to current quarter
const currentQuarter = quarters?.find((q: any) => q.is_current)
if (currentQuarter && !quarterId) {
setQuarterId(currentQuarter.id)
}
async function handleCreate() {
if (!title.trim() || !quarterId || !user) return
await supabase.from('rocks').insert({
title: title.trim(),
owner_id: user.id,
group_id: groupId,
quarter_id: quarterId,
target_completion_date: targetDate || null,
notes: notes || null,
})
setTitle('')
setTargetDate('')
setNotes('')
setOpen(false)
mutate(`rocks-${groupage 1 / 5next ›