Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -190,19 +190,24 @@ export async function fetchGatewayModelsPage({
export async function fetchGatewayFavoriteModels(
wsId: string
): Promise<GatewayModelUi[]> {
const { createClient } = await import('@tuturuuu/supabase/next/client');
const supabase = createClient();
const { data: favorites, error: favoritesError } = await supabase
.from('ai_model_favorites')
.select('model_id')
.eq('ws_id', wsId);
const response = await fetch(
`/api/v1/workspaces/${wsId}/ai/model-favorites`,
{
cache: 'no-store',
}
);

if (favoritesError || !favorites?.length) return [];
if (!response.ok) return [];

const { favoriteIds = [] } = (await response.json()) as {
favoriteIds?: string[];
};
if (favoriteIds.length === 0) return [];

const favoriteIds = new Set(favorites.map((favorite) => favorite.model_id));
const favoriteIdSet = new Set(favoriteIds);
const catalog = await fetchGatewayModelCatalog();

return catalog.filter((model) => favoriteIds.has(model.value));
return catalog.filter((model) => favoriteIdSet.has(model.value));
}

export async function fetchGatewayModels(): Promise<GatewayModelUi[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import {
useQueryClient,
} from '@tanstack/react-query';
import { matchesAllowedModel } from '@tuturuuu/ai/credits/model-mapping';
import { createClient } from '@tuturuuu/supabase/next/client';
import {
listWorkspaceAiModelFavorites,
toggleWorkspaceAiModelFavorite,
} from '@tuturuuu/internal-api/ai';
import type { AIModelUI } from '@tuturuuu/types';
import { useAiCredits } from '@tuturuuu/ui/hooks/use-ai-credits';
import { toast } from '@tuturuuu/ui/sonner';
Expand All @@ -30,54 +33,16 @@ import type { ModelFavoriteToggleHandler } from './types';
import { useSortedProviderList } from './use-provider-logo-availability';

async function fetchFavorites(wsId: string): Promise<Set<string>> {
const supabase = createClient();
const { data, error } = await supabase
.from('ai_model_favorites')
.select('model_id')
.eq('ws_id', wsId);

if (error || !data?.length) return new Set();
return new Set(data.map((row) => row.model_id));
const favoriteIds = await listWorkspaceAiModelFavorites(wsId);
return new Set(favoriteIds);
}

async function toggleFavorite(
wsId: string,
modelId: string,
isFavorited: boolean
): Promise<void> {
const supabase = await createClient();
const {
data: { user },
} = await supabase.auth.getUser();

if (!user) {
throw new Error('Authentication required');
}

if (isFavorited) {
const { error } = await supabase
.from('ai_model_favorites')
.delete()
.eq('ws_id', wsId)
.eq('user_id', user.id)
.eq('model_id', modelId);

if (error) {
throw new Error(error.message || 'Failed to update favorites');
}

return;
}

const { error } = await supabase.from('ai_model_favorites').insert({
ws_id: wsId,
user_id: user.id,
model_id: modelId,
});

if (error) {
throw new Error(error.message || 'Failed to update favorites');
}
await toggleWorkspaceAiModelFavorite(wsId, { modelId, isFavorited });
}

interface UseMiraModelSelectorDataParams {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useQuery } from '@tanstack/react-query';
import { Settings, ShieldAlert, X } from '@tuturuuu/icons';
import { createClient } from '@tuturuuu/supabase/next/client';
import { getWorkspacePermissionSetupStatus } from '@tuturuuu/internal-api/settings';
import { Alert, AlertDescription, AlertTitle } from '@tuturuuu/ui/alert';
import { Button } from '@tuturuuu/ui/button';
import Link from 'next/link';
Expand All @@ -23,44 +23,8 @@ export default function PermissionSetupBanner({

const { data: hasPermissions, isLoading } = useQuery({
queryKey: ['workspace-permissions-configured', wsId],
queryFn: async () => {
const supabase = createClient();

// Check for default permissions
const { data: defaultPerms, error: defaultError } = await supabase
.from('workspace_default_permissions')
.select('permission')
.eq('ws_id', wsId)
.eq('enabled', true)
.limit(1);

if (defaultError) {
console.error('Error checking default permissions:', defaultError);
return true; // Don't show banner on error
}

if (defaultPerms && defaultPerms.length > 0) {
return true;
}

// Check for roles with permissions
const { data: roles, error: rolesError } = await supabase
.from('workspace_roles')
.select('id')
.eq('ws_id', wsId)
.limit(1);

if (rolesError) {
console.error('Error checking roles:', rolesError);
return true; // Don't show banner on error
}

if (roles && roles.length > 0) {
return true;
}

return false;
},
queryFn: async () =>
(await getWorkspacePermissionSetupStatus(wsId)).hasConfiguredPermissions,
staleTime: 1000 * 60 * 5, // 5 minutes
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { useLocalStorage } from '@mantine/hooks';
import { createClient } from '@tuturuuu/supabase/next/client';
import { getWorkspace } from '@tuturuuu/internal-api/workspaces';
import { useCallback, useEffect, useRef, useState } from 'react';
import type { MigrationModule } from '../modules';
import {
Expand Down Expand Up @@ -347,14 +347,9 @@ export function useMigrationState(
setTargetWorkspaceName(null);

try {
const supabase = createClient();
const { data, error } = await supabase
.from('workspaces')
.select('name')
.eq('id', wsId)
.single();

if (error || !data) {
const data = await getWorkspace(wsId);

if (!data) {
setTargetWorkspaceName('');
} else {
setTargetWorkspaceName(data.name || '');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useQuery } from '@tanstack/react-query';
import { Banknote, Monitor, PencilRuler, Users } from '@tuturuuu/icons';
import { createClient } from '@tuturuuu/supabase/next/client';
import { listWorkspaceMembers } from '@tuturuuu/internal-api/workspaces';
import type { SupabaseUser } from '@tuturuuu/supabase/next/user';
import type { PermissionId, WorkspaceRole } from '@tuturuuu/types';
import type { WorkspaceUser } from '@tuturuuu/types/primitives/WorkspaceUser';
Expand Down Expand Up @@ -256,21 +256,6 @@ export function RoleForm({ wsId, user, data, forceDefault, onFinish }: Props) {
}

async function getWorkspaceUsers(wsId: string) {
const supabase = createClient();

const queryBuilder = supabase
.from('workspace_members')
.select(
'id:user_id, ...users(display_name, ...user_private_details(email))',
{
count: 'exact',
}
)
.eq('ws_id', wsId)
.order('user_id');

const { data, error, count } = await queryBuilder;
if (error) throw error;

return { data, count } as { data: WorkspaceUser[]; count: number };
const data = (await listWorkspaceMembers(wsId)) as WorkspaceUser[];
return { data, count: data.length };
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useQuery } from '@tanstack/react-query';
import { Plus, Search, User, UserPlus, Users, X } from '@tuturuuu/icons';
import { createClient } from '@tuturuuu/supabase/next/client';
import { listRoleMembers } from '@tuturuuu/internal-api/roles';
import { listWorkspaceMembers } from '@tuturuuu/internal-api/workspaces';
import type { WorkspaceUser } from '@tuturuuu/types/primitives/WorkspaceUser';
import { Avatar, AvatarFallback, AvatarImage } from '@tuturuuu/ui/avatar';
import { Badge } from '@tuturuuu/ui/badge';
Expand Down Expand Up @@ -34,7 +35,7 @@ export default function RoleFormMembersSection({

const roleMembersQuery = useQuery({
queryKey: ['workspaces', wsId, 'roles', roleId, 'members'],
queryFn: roleId ? () => getRoleMembers(roleId) : undefined,
queryFn: roleId ? () => getRoleMembers(wsId, roleId) : undefined,
enabled: !!roleId,
});

Expand Down Expand Up @@ -339,37 +340,13 @@ export default function RoleFormMembersSection({
}

async function getWorkspaceUsers(wsId: string) {
const supabase = createClient();

const queryBuilder = supabase
.from('workspace_members')
.select(
'id:user_id, ...users(display_name, full_name, avatar_url, ...user_private_details(email))',
{
count: 'exact',
}
)
.eq('ws_id', wsId)
.order('user_id');

const { data, error, count } = await queryBuilder;
if (error) throw error;

return { data, count } as { data: WorkspaceUser[]; count: number };
const data = (await listWorkspaceMembers(wsId)) as WorkspaceUser[];
return { data, count: data.length };
}

async function getRoleMembers(roleId: string) {
const supabase = createClient();

const queryBuilder = supabase
.from('workspace_role_members')
.select('...users!inner(id, display_name, avatar_url)', {
count: 'exact',
})
.eq('role_id', roleId);

const { data, count, error } = await queryBuilder;
if (error) throw error;

return { data, count } as { data: WorkspaceUser[]; count: number };
async function getRoleMembers(wsId: string, roleId: string) {
return (await listRoleMembers(wsId, roleId)) as {
data: WorkspaceUser[];
count: number;
};
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
'use client';

import { createClient } from '@tuturuuu/supabase/next/client';
import { updateWorkspaceCourseModule } from '@tuturuuu/internal-api/education';
import type { JSONContent } from '@tuturuuu/types/tiptap';
import { toast } from '@tuturuuu/ui/sonner';
import { RichTextEditor } from '@tuturuuu/ui/text-editor/editor';
import { useTranslations } from 'next-intl';
import { useState } from 'react';

interface Props {
wsId: string;
courseId: string;
moduleId: string;
content?: JSONContent;
}

export function ModuleContentEditor({ courseId, moduleId, content }: Props) {
export function ModuleContentEditor({
wsId,
courseId,
moduleId,
content,
}: Props) {
const [post, setPost] = useState<JSONContent | null>(content || null);
const t = useTranslations();

Expand All @@ -23,15 +29,12 @@ export function ModuleContentEditor({ courseId, moduleId, content }: Props) {
};

const saveContentToDB = async (content: JSONContent | null) => {
const supabase = createClient();

const { error } = await supabase
.from('workspace_course_modules')
.update({ content })
.eq('id', moduleId)
.eq('course_id', courseId);

if (error) {
try {
await updateWorkspaceCourseModule(wsId, moduleId, {
course_id: courseId,
content,
});
} catch (error) {
console.log(error);
toast.error(t('common.error_saving_content'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ export const metadata: Metadata = {

interface Props {
params: Promise<{
wsId: string;
courseId: string;
moduleId: string;
}>;
}

export default async function ModuleContentPage({ params }: Props) {
const { courseId, moduleId } = await params;
const { wsId, courseId, moduleId } = await params;
const t = await getTranslations();

const getContent = async (courseId: string, moduleId: string) => {
Expand Down Expand Up @@ -60,6 +61,7 @@ export default async function ModuleContentPage({ params }: Props) {
showSecondaryTrigger
/>
<ModuleContentEditor
wsId={wsId}
courseId={courseId}
moduleId={moduleId}
content={content}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { Pencil, Trash, X } from '@tuturuuu/icons';
import { createClient } from '@tuturuuu/supabase/next/client';
import { deleteWorkspaceFlashcard } from '@tuturuuu/internal-api/education';
import {
AlertDialog,
AlertDialogAction,
Expand Down Expand Up @@ -53,22 +53,16 @@ export default function ClientFlashcards({
}) {
const router = useRouter();
const t = useTranslations();
const supabase = createClient();

const [editingCardId, setEditingCardId] = useState<string | null>(null);

const onDelete = async (id: string) => {
const { error } = await supabase
.from('workspace_flashcards')
.delete()
.eq('id', id);

if (error) {
try {
await deleteWorkspaceFlashcard(wsId, id);
router.refresh();
} catch (error) {
console.log(error);
return;
}

router.refresh();
};

return (
Expand Down
Loading
Loading