feat: lint codebase and run precommit hook
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
let { message, title } = $derived.by(() => {
|
||||
const fields = {
|
||||
title: '',
|
||||
message: '',
|
||||
message: ''
|
||||
};
|
||||
if (!type) return fields;
|
||||
|
||||
@@ -42,10 +42,7 @@
|
||||
});
|
||||
|
||||
function handleSupport() {
|
||||
window.open(
|
||||
'mailto:[email protected]?subject=Email Verification Issue&body=Error Type: ' + type,
|
||||
'_blank'
|
||||
);
|
||||
window.open('mailto:[email protected]?subject=Email Verification Issue&body=Error Type: ' + type, '_blank');
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -55,7 +52,7 @@
|
||||
</svelte:head>
|
||||
|
||||
<Empty
|
||||
title={title}
|
||||
{title}
|
||||
description={message}
|
||||
icon={OctagonAlertIcon}
|
||||
variant="page"
|
||||
@@ -63,34 +60,27 @@
|
||||
showLogo={true}
|
||||
class="h-fit! flex-none! max-h-none!"
|
||||
>
|
||||
{#if type === 'legacy_method_blocked'}
|
||||
<div
|
||||
class="rounded-md border border-yellow-200 bg-yellow-50 p-4 dark:border-yellow-800 dark:bg-yellow-900/20"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<TriangleAlertIcon class="h-5 w-5 flex-shrink-0 text-yellow-400" />
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
|
||||
{$t('email_verification.security_notice.title')}
|
||||
</h3>
|
||||
<p class="mt-1 text-xs text-yellow-700 dark:text-yellow-300">
|
||||
{$t('email_verification.security_notice.message')}
|
||||
</p>
|
||||
{#if type === 'legacy_method_blocked'}
|
||||
<div class="rounded-md border border-yellow-200 bg-yellow-50 p-4 dark:border-yellow-800 dark:bg-yellow-900/20">
|
||||
<div class="flex items-center">
|
||||
<TriangleAlertIcon class="h-5 w-5 flex-shrink-0 text-yellow-400" />
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
|
||||
{$t('email_verification.security_notice.title')}
|
||||
</h3>
|
||||
<p class="mt-1 text-xs text-yellow-700 dark:text-yellow-300">
|
||||
{$t('email_verification.security_notice.message')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="lex w-full flex-col justify-center gap-4 md:flex-row">
|
||||
<Button onclick={handleSupport} variant="ghost">
|
||||
{$t('email_verification.actions.contact_support')}
|
||||
</Button>
|
||||
<Button onclick={() => goto('/')}>
|
||||
{$t('email_verification.actions.back_to_dashboard')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="lex w-full flex-col justify-center gap-4 md:flex-row">
|
||||
<Button
|
||||
onclick={handleSupport}
|
||||
variant="ghost"
|
||||
>
|
||||
{$t('email_verification.actions.contact_support')}
|
||||
</Button>
|
||||
<Button
|
||||
onclick={() => goto('/')}
|
||||
>
|
||||
{$t('email_verification.actions.back_to_dashboard')}
|
||||
</Button>
|
||||
</div>
|
||||
</Empty>
|
||||
|
||||
@@ -77,8 +77,7 @@
|
||||
}
|
||||
console.log('path', path);
|
||||
console.log('isPublicRoute', isPublicRoute(path));
|
||||
console.log('data', $session.data)
|
||||
|
||||
console.log('data', $session.data);
|
||||
|
||||
// No need to require login for public routes
|
||||
if (isPublicRoute(path) && path !== '/') return;
|
||||
|
||||
@@ -19,9 +19,7 @@ export async function POST({ request }) {
|
||||
|
||||
try {
|
||||
// Clean up expired tokens
|
||||
const { data: cleanupResult, error } = await supabase.rpc(
|
||||
'cleanup_expired_verification_tokens'
|
||||
);
|
||||
const { data: cleanupResult, error } = await supabase.rpc('cleanup_expired_verification_tokens');
|
||||
|
||||
if (error) {
|
||||
console.error('Token cleanup failed:', error);
|
||||
|
||||
@@ -43,14 +43,11 @@ export async function GET({ url, request }) {
|
||||
|
||||
const recent = tokenStats.filter((token) => new Date(token.created_at) > last24Hours);
|
||||
const used = tokenStats.filter((token) => token.used_at);
|
||||
const expired = tokenStats.filter(
|
||||
(token) => new Date(token.expires_at) < now && !token.used_at
|
||||
);
|
||||
const expired = tokenStats.filter((token) => new Date(token.expires_at) < now && !token.used_at);
|
||||
|
||||
// Count unique IPs for anomaly detection
|
||||
const uniqueCreationIPs = new Set(tokenStats.map((t) => t.created_by_ip)).size;
|
||||
const uniqueUsageIPs = new Set(tokenStats.filter((t) => t.used_by_ip).map((t) => t.used_by_ip))
|
||||
.size;
|
||||
const uniqueUsageIPs = new Set(tokenStats.filter((t) => t.used_by_ip).map((t) => t.used_by_ip)).size;
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
@@ -61,8 +58,7 @@ export async function GET({ url, request }) {
|
||||
expired_unused: expired.length,
|
||||
unique_creation_ips: uniqueCreationIPs,
|
||||
unique_usage_ips: uniqueUsageIPs,
|
||||
success_rate:
|
||||
tokenStats.length > 0 ? ((used.length / tokenStats.length) * 100).toFixed(1) : 0
|
||||
success_rate: tokenStats.length > 0 ? ((used.length / tokenStats.length) * 100).toFixed(1) : 0
|
||||
},
|
||||
recent_activity: recent.slice(0, 10).map((token) => ({
|
||||
created_at: token.created_at,
|
||||
|
||||
@@ -108,9 +108,7 @@ async function getCourseAnalytics(supabase: any, courseId: string): Promise<Cour
|
||||
|
||||
// Get student analytics
|
||||
const studentAnalytics = await Promise.all(
|
||||
members
|
||||
.filter((member) => member.role_id === 3)
|
||||
.map((member) => getStudentOverview(supabase, courseId, member))
|
||||
members.filter((member) => member.role_id === 3).map((member) => getStudentOverview(supabase, courseId, member))
|
||||
);
|
||||
|
||||
analytics.students = studentAnalytics.filter((student): student is StudentOverview => student !== null);
|
||||
@@ -155,11 +153,7 @@ async function getLastLogin(supabase: any, userId: string): Promise<string | und
|
||||
}
|
||||
}
|
||||
|
||||
async function getStudentOverview(
|
||||
supabase: any,
|
||||
courseId: string,
|
||||
member: any
|
||||
): Promise<StudentOverview | null> {
|
||||
async function getStudentOverview(supabase: any, courseId: string, member: any): Promise<StudentOverview | null> {
|
||||
try {
|
||||
// Use the same service function that the working analytics/user API uses
|
||||
const { data: courseProgressData, error: progressError } = await fetchProfileCourseProgress(
|
||||
|
||||
@@ -40,12 +40,7 @@ async function getCourse(supabase: any, courseId: string) {
|
||||
return course;
|
||||
}
|
||||
|
||||
async function getGroupMembers(
|
||||
supabase: any,
|
||||
groupId: string,
|
||||
isStudent: boolean,
|
||||
userMembership: any
|
||||
) {
|
||||
async function getGroupMembers(supabase: any, groupId: string, isStudent: boolean, userMembership: any) {
|
||||
if (isStudent) {
|
||||
return {
|
||||
id: groupId,
|
||||
@@ -53,11 +48,7 @@ async function getGroupMembers(
|
||||
};
|
||||
}
|
||||
|
||||
const { data: group, error } = await supabase
|
||||
.from('group')
|
||||
.select(GROUP_MEMBERS_SELECT)
|
||||
.eq('id', groupId)
|
||||
.single();
|
||||
const { data: group, error } = await supabase.from('group').select(GROUP_MEMBERS_SELECT).eq('id', groupId).single();
|
||||
|
||||
if (error) {
|
||||
throw new Error('Error fetching group members');
|
||||
|
||||
@@ -19,11 +19,7 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||
const supabase = getServerSupabase();
|
||||
|
||||
// Get course group_id for permission check
|
||||
const { data: course } = await supabase
|
||||
.from('course')
|
||||
.select('group_id')
|
||||
.eq('id', courseId)
|
||||
.single();
|
||||
const { data: course } = await supabase.from('course').select('group_id').eq('id', courseId).single();
|
||||
|
||||
if (!course) {
|
||||
return json({ success: false, message: 'Course not found' }, { status: 404 });
|
||||
@@ -41,9 +37,7 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||
);
|
||||
}
|
||||
|
||||
const { data: exercises, error } = await supabase
|
||||
.rpc('get_exercises')
|
||||
.eq('course_id', courseId);
|
||||
const { data: exercises, error } = await supabase.rpc('get_exercises').eq('course_id', courseId);
|
||||
|
||||
if (error) {
|
||||
throw new Error('Error fetching exercises');
|
||||
|
||||
@@ -19,11 +19,7 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||
const supabase = getServerSupabase();
|
||||
|
||||
// Get course group_id for permission check
|
||||
const { data: course } = await supabase
|
||||
.from('course')
|
||||
.select('group_id')
|
||||
.eq('id', courseId)
|
||||
.single();
|
||||
const { data: course } = await supabase.from('course').select('group_id').eq('id', courseId).single();
|
||||
|
||||
if (!course) {
|
||||
return json({ success: false, message: 'Course not found' }, { status: 404 });
|
||||
|
||||
@@ -37,8 +37,8 @@ async function onPayload(payload: PolarWebhookPayload) {
|
||||
if (isSubscriptionActive) {
|
||||
try {
|
||||
const planData = {
|
||||
orgId,
|
||||
triggeredBy: parseInt(triggeredBy),
|
||||
orgId,
|
||||
triggeredBy: parseInt(triggeredBy),
|
||||
planName: PLAN.EARLY_ADOPTER as 'EARLY_ADOPTER' | 'ENTERPRISE' | 'BASIC',
|
||||
subscriptionId,
|
||||
payload: payload.data as unknown as Record<string, unknown>
|
||||
@@ -56,9 +56,9 @@ async function onPayload(payload: PolarWebhookPayload) {
|
||||
// Handle Cancel Subscription
|
||||
try {
|
||||
const result = await OrgPlanApiServer.cancelOrgPlan({
|
||||
subscriptionId,
|
||||
subscriptionId,
|
||||
payload: payload.data as unknown as Record<string, unknown>
|
||||
});
|
||||
});
|
||||
console.log('Subscription canceled', result);
|
||||
} catch (error) {
|
||||
console.error('Error canceling org plan', error);
|
||||
@@ -67,9 +67,9 @@ async function onPayload(payload: PolarWebhookPayload) {
|
||||
// Handle Update Subscription
|
||||
try {
|
||||
const result = await OrgPlanApiServer.updateOrgPlan({
|
||||
subscriptionId,
|
||||
subscriptionId,
|
||||
payload: payload.data as unknown as Record<string, unknown>
|
||||
});
|
||||
});
|
||||
console.log('Subscription updated', result);
|
||||
} catch (error) {
|
||||
console.error('Error updating org plan', error);
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
<Sidebar.Provider>
|
||||
<CourseSidebar {path} />
|
||||
|
||||
<Sidebar.Inset class="w-[calc(100vw-var(--sidebar-width))] overflow-x-hidden group-data-[collapsible=icon]:w-[calc(100vw-var(--sidebar-width-icon))]">
|
||||
<Sidebar.Inset
|
||||
class="w-[calc(100vw-var(--sidebar-width))] overflow-x-hidden group-data-[collapsible=icon]:w-[calc(100vw-var(--sidebar-width-icon))]"
|
||||
>
|
||||
<CourseHeader />
|
||||
|
||||
<Page.Root
|
||||
class="mx-auto flex px-4 lg:max-w-6xl"
|
||||
>
|
||||
<Page.Root class="mx-auto flex px-4 lg:max-w-6xl">
|
||||
{@render children?.()}
|
||||
</Page.Root>
|
||||
</Sidebar.Inset>
|
||||
|
||||
@@ -130,12 +130,6 @@
|
||||
</div>
|
||||
|
||||
<div class="my-4 flex w-full items-center justify-center">
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={disableSubmit || loading}
|
||||
loading={loading || !$profile.id}
|
||||
>
|
||||
Join Course
|
||||
</Button>
|
||||
<Button type="submit" disabled={disableSubmit || loading} loading={loading || !$profile.id}>Join Course</Button>
|
||||
</div>
|
||||
</AuthUI>
|
||||
|
||||
@@ -10,4 +10,3 @@
|
||||
<Page.Root class="w-full pb-10 md:max-w-3xl lg:mx-auto">
|
||||
{@render children?.()}
|
||||
</Page.Root>
|
||||
|
||||
|
||||
@@ -18,4 +18,3 @@
|
||||
<IntegrationsPage />
|
||||
{/snippet}
|
||||
</Page.Body>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user