From 485d581f201a4da01ca9158d3844c1cc98995a9b Mon Sep 17 00:00:00 2001 From: Durdana Sultana Date: Sat, 18 Jul 2026 15:51:38 +0530 Subject: [PATCH 1/5] added --- src/components/AvatarUpload.tsx | 1 + src/components/dashboard/RecentActivity.tsx | 8 +- src/integrations/supabase/types.ts | 845 ++++++++++++++++++ src/pages/ReviewSubmission.tsx | 18 +- ...000003_app_bootstrap_and_notifications.sql | 16 + 5 files changed, 875 insertions(+), 13 deletions(-) diff --git a/src/components/AvatarUpload.tsx b/src/components/AvatarUpload.tsx index a7e2fa1e..f47e40ed 100644 --- a/src/components/AvatarUpload.tsx +++ b/src/components/AvatarUpload.tsx @@ -1,6 +1,7 @@ import React, { useRef, useState } from "react"; import { Camera, Loader2 } from "lucide-react"; import { supabase } from "@/integrations/supabase/client"; +import { API_BASE_URL } from "@/config/api"; type AvatarUploadProps = { currentAvatarUrl: string; diff --git a/src/components/dashboard/RecentActivity.tsx b/src/components/dashboard/RecentActivity.tsx index 675a56db..38b32869 100644 --- a/src/components/dashboard/RecentActivity.tsx +++ b/src/components/dashboard/RecentActivity.tsx @@ -47,11 +47,9 @@ export default function RecentActivity() { .order("created_at", { ascending: false }) .limit(3), supabase - .from("resources") - .select("id, title, created_at") - .eq("user_id", user.id) - .order("created_at", { ascending: false }) - .limit(3), + .from("resources") + .select("id, title, created_at") + .eq("uploaded_by", user.id), supabase .from("study_room_participants") .select("room_id, joined_at, study_rooms(topic)") diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index e69de29b..56d607d3 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -0,0 +1,845 @@ +export type Json = + | string + | number + | boolean + | null + | { [key: string]: Json | undefined } + | Json[] + +export type Database = { + // Allows to automatically instantiate createClient with right options + // instead of createClient(URL, KEY) + __InternalSupabase: { + PostgrestVersion: "14.5" + } + public: { + Tables: { + mentorship_paths: { + Row: { + id: string + mentor_id: string + mentee_id: string + goal: string + status: string + created_at: string + updated_at: string + } + Insert: { + id?: string + mentor_id: string + mentee_id: string + goal: string + status?: string + created_at?: string + updated_at?: string + } + Update: { + id?: string + mentor_id?: string + mentee_id?: string + goal?: string + status?: string + created_at?: string + updated_at?: string + } + Relationships: [ + { + foreignKeyName: "mentorship_paths_mentee_id_fkey" + columns: ["mentee_id"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] + }, + { + foreignKeyName: "mentorship_paths_mentor_id_fkey" + columns: ["mentor_id"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] + } + ] + } + mentorship_milestones: { + Row: { + id: string + path_id: string + title: string + description: string | null + is_completed: boolean + due_date: string | null + created_at: string + updated_at: string + } + Insert: { + id?: string + path_id: string + title: string + description?: string | null + is_completed?: boolean + due_date?: string | null + created_at?: string + updated_at?: string + } + Update: { + id?: string + path_id?: string + title?: string + description?: string | null + is_completed?: boolean + due_date?: string | null + created_at?: string + updated_at?: string + } + Relationships: [ + { + foreignKeyName: "mentorship_milestones_path_id_fkey" + columns: ["path_id"] + isOneToOne: false + referencedRelation: "mentorship_paths" + referencedColumns: ["id"] + } + ] + } + peer_submissions: { + Row: { + id: string + user_id: string + title: string + description: string | null + content_url: string | null + content: string | null + is_anonymous: boolean + status: string + created_at: string + } + Insert: { + id?: string + user_id: string + title: string + description?: string | null + content_url?: string | null + content?: string | null + is_anonymous?: boolean + status?: string + created_at?: string + } + Update: { + id?: string + user_id?: string + title?: string + description?: string | null + content_url?: string | null + content?: string | null + is_anonymous?: boolean + status?: string + created_at?: string + } + Relationships: [ + { + foreignKeyName: "peer_submissions_user_id_fkey" + columns: ["user_id"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] + } + ] + } + peer_reviews: { + Row: { + id: string + submission_id: string + reviewer_id: string + feedback: string + rating: number | null + created_at: string + } + Insert: { + id?: string + submission_id: string + reviewer_id: string + feedback: string + rating?: number | null + created_at?: string + } + Update: { + id?: string + submission_id?: string + reviewer_id?: string + feedback?: string + rating?: number | null + created_at?: string + } + Relationships: [ + { + foreignKeyName: "peer_reviews_submission_id_fkey" + columns: ["submission_id"] + isOneToOne: false + referencedRelation: "peer_submissions" + referencedColumns: ["id"] + }, + { + foreignKeyName: "peer_reviews_reviewer_id_fkey" + columns: ["reviewer_id"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] + } + ] + } + + chat_messages: { + Row: { + created_at: string + id: number + } + Insert: { + created_at?: string + id?: number + } + Update: { + created_at?: string + id?: number + } + Relationships: [] + } + messages: { + Row: { + content: string | null + created_at: string | null + id: string + message: string | null + read_at: string | null + receiver_id: string | null + sender_id: string | null + text: string | null + } + Insert: { + content?: string | null + created_at?: string | null + id?: string + message?: string | null + read_at?: string | null + receiver_id?: string | null + sender_id?: string | null + text?: string | null + } + Update: { + content?: string | null + created_at?: string | null + id?: string + message?: string | null + read_at?: string | null + receiver_id?: string | null + sender_id?: string | null + text?: string | null + } + Relationships: [] + } + leaderboard: { + Row: { + id: string + user_id: string + username: string + avatar_url: string | null + xp: number + streak: number + sessions_joined: number + badges: string[] + updated_at: string + } + Insert: { + id?: string + user_id: string + username: string + avatar_url?: string | null + xp?: number + streak?: number + sessions_joined?: number + badges?: string[] + updated_at?: string + } + Update: { + id?: string + user_id?: string + username?: string + avatar_url?: string | null + xp?: number + streak?: number + sessions_joined?: number + badges?: string[] + updated_at?: string + } + Relationships: [ + { + foreignKeyName: "leaderboard_user_id_fkey" + columns: ["user_id"] + isOneToOne: true + referencedRelation: "profiles" + referencedColumns: ["id"] + } + ] + } + profiles: { + Row: { + avatar_url: string | null + bio: string | null + created_at: string | null + email: string | null + id: string + last_seen: string | null + name: string | null + skills: string[] | null + is_mentor: boolean + is_learner: boolean + points: number | null + sessions_completed: number | null + rating: number | null + badges: string[] | null + interests: string[] | null + teach_subjects: string[] | null + learn_subjects: string[] | null + updated_at: string | null + streak: number + last_active: string | null + restoration_used_today: boolean + restoration_date: string | null + is_in_focus_mode: boolean | null + focus_time_this_week: number | null + learning_style: string | null + availability: string | null + preferred_language: string | null + timezone: string | null + } + Insert: { + avatar_url?: string | null + bio?: string | null + created_at?: string | null + email?: string | null + id: string + last_seen?: string | null + name?: string | null + skills?: string[] | null + is_mentor?: boolean + is_learner?: boolean + points?: number | null + sessions_completed?: number | null + rating?: number | null + badges?: string[] | null + interests?: string[] | null + teach_subjects?: string[] | null + learn_subjects?: string[] | null + updated_at?: string | null + streak?: number + last_active?: string | null + restoration_used_today?: boolean + restoration_date?: string | null + learning_style?: string | null + availability?: string | null + preferred_language?: string | null + timezone?: string | null + } + Update: { + avatar_url?: string | null + bio?: string | null + created_at?: string | null + email?: string | null + id?: string + last_seen?: string | null + name?: string | null + skills?: string[] | null + is_mentor?: boolean + is_learner?: boolean + points?: number | null + sessions_completed?: number | null + rating?: number | null + badges?: string[] | null + interests?: string[] | null + teach_subjects?: string[] | null + learn_subjects?: string[] | null + updated_at?: string | null + streak?: number + last_active?: string | null + restoration_used_today?: boolean + restoration_date?: string | null + learning_style?: string | null + availability?: string | null + preferred_language?: string | null + timezone?: string | null + } + Relationships: [] + } + resources: { + Row: { + id: string + title: string + description: string | null + file_url: string + file_size: number | null + tags: string[] | null + file_type: string + uploaded_by: string + created_at: string + } + Insert: { + id?: string + title: string + description?: string | null + file_url: string + file_size?: number | null + tags?: string[] | null + file_type: string + uploaded_by: string + created_at?: string + } + Update: { + id?: string + title?: string + description?: string | null + file_url?: string + file_size?: number | null + tags?: string[] | null + file_type?: string + uploaded_by?: string + created_at?: string + } + Relationships: [] + } + resource_votes: { + Row: { + id: string + resource_id: string + user_id: string + vote_type: number + created_at: string + } + Insert: { + id?: string + resource_id: string + user_id: string + vote_type: number + created_at?: string + } + Update: { + id?: string + resource_id?: string + user_id?: string + vote_type?: number + created_at?: string + } + Relationships: [] + } + saved_resources: { + Row: { + id: string + resource_id: string + user_id: string + created_at: string + } + Insert: { + id?: string + resource_id: string + user_id: string + created_at?: string + } + Update: { + id?: string + resource_id?: string + user_id?: string + created_at?: string + } + Relationships: [] + } + skill_endorsements: { + Row: { + id: string + skill: string + endorsed_user_id: string + endorser_id: string + created_at: string + } + Insert: { + id?: string + skill: string + endorsed_user_id: string + endorser_id: string + created_at?: string + } + Update: { + id?: string + skill?: string + endorsed_user_id?: string + endorser_id?: string + created_at?: string + } + Relationships: [] + } + study_rooms: { + Row: { + id: string + topic: string + created_by: string | null + created_at: string + is_private: boolean + } + Insert: { + id?: string + topic: string + created_by?: string | null + created_at?: string + is_private?: boolean + } + Update: { + id?: string + topic?: string + created_by?: string | null + created_at?: string + is_private?: boolean + } + Relationships: [ + { + foreignKeyName: "study_rooms_created_by_fkey" + columns: ["created_by"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] + } + ] + } + study_room_messages: { + Row: { + id: string + room_id: string | null + profile_id: string | null + content: string + created_at: string + } + Insert: { + id?: string + room_id?: string | null + profile_id?: string | null + content: string + created_at?: string + } + Update: { + id?: string + room_id?: string | null + profile_id?: string | null + content?: string + created_at?: string + } + Relationships: [ + { + foreignKeyName: "study_room_messages_profile_id_fkey" + columns: ["profile_id"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] + }, + { + foreignKeyName: "study_room_messages_room_id_fkey" + columns: ["room_id"] + isOneToOne: false + referencedRelation: "study_rooms" + referencedColumns: ["id"] + } + ] + } + study_room_participants: { + Row: { + room_id: string + profile_id: string + joined_at: string + } + Insert: { + room_id: string + profile_id: string + joined_at?: string + } + Update: { + room_id?: string + profile_id?: string + joined_at?: string + } + Relationships: [ + { + foreignKeyName: "study_room_participants_profile_id_fkey" + columns: ["profile_id"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] + }, + { + foreignKeyName: "study_room_participants_room_id_fkey" + columns: ["room_id"] + isOneToOne: false + referencedRelation: "study_rooms" + referencedColumns: ["id"] + } + ] + } + sessions: { + Row: { + created_at: string + description: string | null + id: number + scheduled_at: string | null + /** duration_minutes – NEW column added by session scheduling migration */ + duration_minutes: number + /** status values: 'scheduled' | 'live' | 'ended' */ + status: string + student_id: string | null + mentor_id: string | null + seat_limit: number | null + participants: number + title: string | null + tags: string[] | null + } + Insert: { + created_at?: string + description?: string | null + id?: number + scheduled_at?: string | null + duration_minutes?: number + status?: string + student_id?: string | null + mentor_id?: string | null + seat_limit?: number | null + participants?: number + title?: string | null + tags?: string[] | null + } + Update: { + created_at?: string + description?: string | null + id?: number + scheduled_at?: string | null + duration_minutes?: number + status?: string + student_id?: string | null + mentor_id?: string | null + seat_limit?: number | null + participants?: number + title?: string | null + tags?: string[] | null + } + Relationships: [] + } + users: { + Row: { + created_at: string | null + email: string | null + id: string + learning_goals: string | null + name: string | null + skills: string | null + } + Insert: { + created_at?: string | null + email?: string | null + id?: string + learning_goals?: string | null + name?: string | null + skills?: string | null + } + Update: { + created_at?: string | null + email?: string | null + id?: string + learning_goals?: string | null + name?: string | null + skills?: string | null + } + Relationships: [] + } + } + Views: { + skill_endorsement_counts: { + Row: { + endorsed_user_id: string + skill: string + endorsement_count: number + } + Relationships: [] + } + } + Functions: { + award_activity_xp: { + Args: { _activity_type: string } + Returns: undefined + } + get_user_rank: { + Args: { + p_user_id: string + p_filter?: string + } + Returns: number + } + has_role: { + Args: { + _role: string + _user_id: string + } + Returns: boolean + } + invite_to_study_room: { + Args: { + p_room_id: string + p_user_email: string + } + Returns: undefined + } + join_leaderboard: { + Args: { + _username: string + _avatar_url: string | null + } + Returns: undefined + } + join_public_study_room: { + Args: { p_room_id: string } + Returns: undefined + } + join_session: { + Args: { p_session_id: string } + Returns: undefined + } + mark_messages_as_read: { + Args: { message_ids: string[] } + Returns: undefined + } + tick_session_statuses: { + Args: Record + Returns: undefined + } + } + Enums: { + [_ in never]: never + } + CompositeTypes: { + [_ in never]: never + } + } +} + +type DatabaseWithoutInternals = Omit + +type DefaultSchema = DatabaseWithoutInternals[Extract] + +export type Tables< + DefaultSchemaTableNameOrOptions extends + | keyof (DefaultSchema["Tables"] & DefaultSchema["Views"]) + | { schema: keyof DatabaseWithoutInternals }, + TableName extends DefaultSchemaTableNameOrOptions extends { + schema: keyof DatabaseWithoutInternals + } + ? keyof (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & + DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"]) + : never = never, +> = DefaultSchemaTableNameOrOptions extends { + schema: keyof DatabaseWithoutInternals +} + ? (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & + DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"])[TableName] extends { + Row: infer R + } + ? R + : never + : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema["Tables"] & + DefaultSchema["Views"]) + ? (DefaultSchema["Tables"] & + DefaultSchema["Views"])[DefaultSchemaTableNameOrOptions] extends { + Row: infer R + } + ? R + : never + : never + +export type TablesInsert< + DefaultSchemaTableNameOrOptions extends + | keyof DefaultSchema["Tables"] + | { schema: keyof DatabaseWithoutInternals }, + TableName extends DefaultSchemaTableNameOrOptions extends { + schema: keyof DatabaseWithoutInternals + } + ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] + : never = never, +> = DefaultSchemaTableNameOrOptions extends { + schema: keyof DatabaseWithoutInternals +} + ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { + Insert: infer I + } + ? I + : never + : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] + ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { + Insert: infer I + } + ? I + : never + : never + +export type TablesUpdate< + DefaultSchemaTableNameOrOptions extends + | keyof DefaultSchema["Tables"] + | { schema: keyof DatabaseWithoutInternals }, + TableName extends DefaultSchemaTableNameOrOptions extends { + schema: keyof DatabaseWithoutInternals + } + ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] + : never = never, +> = DefaultSchemaTableNameOrOptions extends { + schema: keyof DatabaseWithoutInternals +} + ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { + Update: infer U + } + ? U + : never + : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] + ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { + Update: infer U + } + ? U + : never + : never + +export type Enums< + DefaultSchemaEnumNameOrOptions extends + | keyof DefaultSchema["Enums"] + | { schema: keyof DatabaseWithoutInternals }, + EnumName extends DefaultSchemaEnumNameOrOptions extends { + schema: keyof DatabaseWithoutInternals + } + ? keyof DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"] + : never = never, +> = DefaultSchemaEnumNameOrOptions extends { + schema: keyof DatabaseWithoutInternals +} + ? DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"][EnumName] + : DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema["Enums"] + ? DefaultSchema["Enums"][DefaultSchemaEnumNameOrOptions] + : never + +export type CompositeTypes< + PublicCompositeTypeNameOrOptions extends + | keyof DefaultSchema["CompositeTypes"] + | { schema: keyof DatabaseWithoutInternals }, + CompositeTypeName extends PublicCompositeTypeNameOrOptions extends { + schema: keyof DatabaseWithoutInternals + } + ? keyof DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"] + : never = never, +> = PublicCompositeTypeNameOrOptions extends { + schema: keyof DatabaseWithoutInternals +} + ? DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName] + : PublicCompositeTypeNameOrOptions extends keyof DefaultSchema["CompositeTypes"] + ? DefaultSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions] + : never + +export const Constants = { + public: { + Enums: {}, + }, +} as const diff --git a/src/pages/ReviewSubmission.tsx b/src/pages/ReviewSubmission.tsx index 7aad750f..8e9cc1fa 100644 --- a/src/pages/ReviewSubmission.tsx +++ b/src/pages/ReviewSubmission.tsx @@ -71,13 +71,15 @@ export default function ReviewSubmission() { // Now both steps happen atomically inside a single SECURITY DEFINER RPC, // and any failure (including a failed status transition) is surfaced // here instead of being ignored. - const { data: reviewRow, error: rpcError } = await supabase.rpc( - "submit_peer_review", - { - p_submission_id: id, - p_feedback: feedback, - } - ); + const { data: reviewRow, error: rpcError } = await (supabase as any).rpc( + "submit_peer_review", + { + p_submission_id: id, + p_feedback: feedback, + } +); + +const review = reviewRow as { id: string }; if (rpcError || !reviewRow) { toast({ @@ -96,7 +98,7 @@ export default function ReviewSubmission() { supabase .from("peer_reviews") .select("*, profiles(name, avatar_url)") - .eq("id", reviewRow.id) + .eq("id", review.id) .single(), supabase .from("peer_submissions") diff --git a/supabase/migrations/20260518000003_app_bootstrap_and_notifications.sql b/supabase/migrations/20260518000003_app_bootstrap_and_notifications.sql index d2a68121..30f35b33 100644 --- a/supabase/migrations/20260518000003_app_bootstrap_and_notifications.sql +++ b/supabase/migrations/20260518000003_app_bootstrap_and_notifications.sql @@ -116,6 +116,22 @@ create table if not exists public.sessions ( updated_at timestamptz not null default now() ); +alter table public.sessions + add column if not exists start_time timestamptz; + +alter table public.sessions + add column if not exists duration text default '1 Hour'; + +alter table public.sessions + add column if not exists is_live boolean not null default false; + +alter table public.sessions + add column if not exists updated_at timestamptz not null default now(); + +create index if not exists sessions_start_time_idx +on public.sessions (start_time) +where start_time is not null; + create index if not exists sessions_status_created_idx on public.sessions (status, created_at desc); From d401635e39bc690af536670b6c2b68dc7248e682 Mon Sep 17 00:00:00 2001 From: Durdana Sultana Date: Mon, 27 Jul 2026 05:20:21 +0530 Subject: [PATCH 2/5] chore: trigger production deployment From ef1080aa0b08fb3985d62165c158c233576b133b Mon Sep 17 00:00:00 2001 From: Durdana Sultana Date: Mon, 27 Jul 2026 05:22:48 +0530 Subject: [PATCH 3/5] chore: deploy correct production version From c72bb5246bfccb98469cf929bcb346cfa2a2a2dc Mon Sep 17 00:00:00 2001 From: Durdana Sultana Date: Mon, 27 Jul 2026 05:35:20 +0530 Subject: [PATCH 4/5] chore: rebuild with updated Supabase config From 28764fc514bbce3e3fc1ecabc712e628e385699e Mon Sep 17 00:00:00 2001 From: Durdana Sultana Date: Mon, 27 Jul 2026 05:54:38 +0530 Subject: [PATCH 5/5] fix: resolve production build errors --- src/App.tsx | 1 - src/hooks/useSessions.ts | 6 +-- src/integrations/supabase/types.ts | 41 +++++++++++++++++-- ...727000000_add_notification_preferences.sql | 4 ++ 4 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 supabase/migrations/20260727000000_add_notification_preferences.sql diff --git a/src/App.tsx b/src/App.tsx index f2c5022c..ee6bef42 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -47,7 +47,6 @@ const Profile = React.lazy(() => import("./pages/Profile")); const EditProfile = React.lazy(() => import("./pages/EditProfile")); const Settings = React.lazy(() => import("./pages/Settings")); const Notifications = React.lazy(() => import("./pages/Notifications")); -const Settings = React.lazy(() => import("./pages/Settings")); const Leaderboard = React.lazy(() => import("./pages/Leaderboard")); const Admin = React.lazy(() => import("./pages/Admin")); const ForgotPassword = React.lazy(() => import("./pages/ForgotPassword")); diff --git a/src/hooks/useSessions.ts b/src/hooks/useSessions.ts index 1cff6961..fc27cc51 100644 --- a/src/hooks/useSessions.ts +++ b/src/hooks/useSessions.ts @@ -180,16 +180,16 @@ export function useSessions(user: any) { const state = roomChannel.presenceState(); setParticipantCount(Math.max(1, Object.keys(state).length)); }) - .on("broadcast", { event: "typing" }, ({ payload }) => { + .on("broadcast", { event: "typing" }, ({ payload }: { payload: { user: string } }) => { if (payload.user === (user?.user_metadata?.full_name || "Someone")) return; setTypingUser(payload.user); clearTimeout(typingTimeoutRef.current); typingTimeoutRef.current = setTimeout(() => setTypingUser(null), 3000); }) - .on("broadcast", { event: "activity" }, ({ payload }) => { + .on("broadcast", { event: "activity" }, ({ payload }: { payload: any }) => { setActivities((prev) => [payload, ...prev]); }) - .subscribe(async (status) => { + .subscribe(async (status: string) => { if (status === "SUBSCRIBED" && isMounted) { await roomChannel.track({ online_at: new Date().toISOString() }); diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index 9bb4d02f..432e3ada 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -15,6 +15,36 @@ export type Database = { } public: { Tables: { + testimonials: { + Row: { + id: string + user_id: string + name: string | null + rating: number | null + review: string + status: string + created_at: string + } + Insert: { + id?: string + user_id: string + name?: string | null + rating?: number | null + review: string + status?: string + created_at?: string + } + Update: { + id?: string + user_id?: string + name?: string | null + rating?: number | null + review?: string + status?: string + created_at?: string + } + Relationships: [] +}, mentorship_paths: { Row: { id: string @@ -104,7 +134,7 @@ export type Database = { peer_submissions: { Row: { id: string - user_id: string + user_id: string | null title: string description: string | null content_url: string | null @@ -115,7 +145,7 @@ export type Database = { } Insert: { id?: string - user_id: string + user_id: string | null title: string description?: string | null content_url?: string | null @@ -126,7 +156,7 @@ export type Database = { } Update: { id?: string - user_id?: string + user_id?: string | null title?: string description?: string | null content_url?: string | null @@ -310,6 +340,7 @@ export type Database = { availability: string | null preferred_language: string | null timezone: string | null + notification_preferences: Json | null } Insert: { avatar_url?: string | null @@ -338,6 +369,7 @@ export type Database = { availability?: string | null preferred_language?: string | null timezone?: string | null + notification_preferences?: Json | null } Update: { avatar_url?: string | null @@ -366,6 +398,7 @@ export type Database = { availability?: string | null preferred_language?: string | null timezone?: string | null + notification_preferences?: Json | null } Relationships: [] } @@ -845,5 +878,5 @@ export const Constants = { }, } as const -export type Database = any; + diff --git a/supabase/migrations/20260727000000_add_notification_preferences.sql b/supabase/migrations/20260727000000_add_notification_preferences.sql new file mode 100644 index 00000000..61774079 --- /dev/null +++ b/supabase/migrations/20260727000000_add_notification_preferences.sql @@ -0,0 +1,4 @@ +-- Add persisted notification preferences to user profiles. + +ALTER TABLE public.profiles +ADD COLUMN IF NOT EXISTS notification_preferences JSONB DEFAULT NULL; \ No newline at end of file