← back to inzamulhaque1__my-blog

Function bodies 345 total

All specs Real LLM only Function bodies
POST function · typescript · L12-L86 (75 LOC)
src/app/api/super-admin/impersonate/[id]/route.ts
export async function POST(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const cookieStore = await cookies();
    const token = cookieStore.get('super-admin-token')?.value;

    if (!token) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const session = await verifySuperAdminToken(token);
    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();
    const { id } = await params;

    // Get tenant
    const tenant = await Tenant.findById(id);
    if (!tenant) {
      return NextResponse.json({ error: 'Tenant not found' }, { status: 404 });
    }

    if (tenant.status !== 'active') {
      return NextResponse.json({ error: 'Tenant is not active' }, { status: 400 });
    }

    // Get owner user
    const owner = await User.findById(tenant.ownerId);
    if (!owner) {
      return NextResponse.json({ error: 'Tenant owner not found' }, { 
verifySuperAdmin function · typescript · L13-L30 (18 LOC)
src/app/api/super-admin/plan-requests/[id]/route.ts
async function verifySuperAdmin() {
  const cookieStore = await cookies();
  const token = cookieStore.get('super-admin-token')?.value;

  if (!token) {
    return null;
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET) as any;
    if (decoded.type !== 'super-admin') {
      return null;
    }
    return decoded;
  } catch {
    return null;
  }
}
GET function · typescript · L32-L71 (40 LOC)
src/app/api/super-admin/plan-requests/[id]/route.ts
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const admin = await verifySuperAdmin();
    if (!admin) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const { id } = await params;

    if (!mongoose.Types.ObjectId.isValid(id)) {
      return NextResponse.json({ error: 'Invalid request ID' }, { status: 400 });
    }

    await connectDB();

    const planRequest = await PlanRequest.findById(id)
      .populate('tenantId', 'name slug plan')
      .populate('requestedBy', 'name email')
      .populate('processedBy', 'name email')
      .lean();

    if (!planRequest) {
      return NextResponse.json({ error: 'Plan request not found' }, { status: 404 });
    }

    return NextResponse.json({
      success: true,
      data: planRequest,
    });
  } catch (error) {
    console.error('Error fetching plan request:', error);
    return NextResponse.json(
      { error: 'Failed to fetc
PATCH function · typescript · L73-L207 (135 LOC)
src/app/api/super-admin/plan-requests/[id]/route.ts
export async function PATCH(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const admin = await verifySuperAdmin();
    if (!admin) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const { id } = await params;

    if (!mongoose.Types.ObjectId.isValid(id)) {
      return NextResponse.json({ error: 'Invalid request ID' }, { status: 400 });
    }

    await connectDB();

    const planRequest = await PlanRequest.findById(id);

    if (!planRequest) {
      return NextResponse.json({ error: 'Plan request not found' }, { status: 404 });
    }

    if (planRequest.status !== 'pending') {
      return NextResponse.json(
        { error: 'This request has already been processed' },
        { status: 400 }
      );
    }

    const body = await request.json();
    const { action, adminNotes, rejectionReason } = body;

    if (!action || !['approve', 'reject'].includes(action)) {
      return NextResponse.json(
 
verifySuperAdmin function · typescript · L10-L27 (18 LOC)
src/app/api/super-admin/plan-requests/route.ts
async function verifySuperAdmin() {
  const cookieStore = await cookies();
  const token = cookieStore.get('super-admin-token')?.value;

  if (!token) {
    return null;
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET) as any;
    if (decoded.type !== 'super-admin') {
      return null;
    }
    return decoded;
  } catch {
    return null;
  }
}
GET function · typescript · L29-L206 (178 LOC)
src/app/api/super-admin/plan-requests/route.ts
export async function GET(request: NextRequest) {
  try {
    const admin = await verifySuperAdmin();
    if (!admin) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();

    const { searchParams } = new URL(request.url);
    const page = Math.max(1, parseInt(searchParams.get('page') || '1'));
    const limit = Math.min(100, Math.max(1, parseInt(searchParams.get('limit') || '10')));
    const status = searchParams.get('status') || '';
    const search = searchParams.get('search')?.trim() || '';
    const skip = (page - 1) * limit;

    // Build filter
    const filter: any = {};

    if (status && ['pending', 'approved', 'rejected', 'cancelled'].includes(status)) {
      filter.status = status;
    }

    // Get stats
    const now = new Date();
    const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);

    const [
      pendingCount,
      approvedCount,
      rejectedCount,
      thisMonthCount,
      total,
     
verifySuperAdmin function · typescript · L9-L26 (18 LOC)
src/app/api/super-admin/plans/route.ts
async function verifySuperAdmin(request: NextRequest) {
  const cookieStore = await cookies();
  const token = cookieStore.get('super-admin-token')?.value;

  if (!token) {
    return null;
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET) as any;
    if (decoded.type !== 'super-admin') {
      return null;
    }
    return decoded;
  } catch {
    return null;
  }
}
Powered by Repobility — scan your code at https://repobility.com
GET function · typescript · L28-L52 (25 LOC)
src/app/api/super-admin/plans/route.ts
export async function GET(request: NextRequest) {
  try {
    const admin = await verifySuperAdmin(request);
    if (!admin) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();

    const plans = await Plan.find()
      .sort({ sortOrder: 1 })
      .lean();

    return NextResponse.json({
      success: true,
      data: plans,
    });
  } catch (error) {
    console.error('Error fetching plans:', error);
    return NextResponse.json(
      { error: 'Failed to fetch plans' },
      { status: 500 }
    );
  }
}
verifySuperAdmin function · typescript · L9-L26 (18 LOC)
src/app/api/super-admin/platform-settings/route.ts
async function verifySuperAdmin() {
  const cookieStore = await cookies();
  const token = cookieStore.get('super-admin-token')?.value;

  if (!token) {
    return null;
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET) as any;
    if (decoded.type !== 'super-admin') {
      return null;
    }
    return decoded;
  } catch {
    return null;
  }
}
GET function · typescript · L28-L56 (29 LOC)
src/app/api/super-admin/platform-settings/route.ts
export async function GET() {
  try {
    const admin = await verifySuperAdmin();
    if (!admin) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();

    // Get or create settings (singleton pattern)
    let settings = await PlatformSettings.findOne();
    if (!settings) {
      settings = await PlatformSettings.create({
        contactEmail: '[email protected]',
      });
    }

    return NextResponse.json({
      success: true,
      data: settings,
    });
  } catch (error) {
    console.error('Error fetching platform settings:', error);
    return NextResponse.json(
      { error: 'Failed to fetch platform settings' },
      { status: 500 }
    );
  }
}
PUT function · typescript · L58-L169 (112 LOC)
src/app/api/super-admin/platform-settings/route.ts
export async function PUT(request: NextRequest) {
  try {
    const admin = await verifySuperAdmin();
    if (!admin) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();

    const body = await request.json();
    const {
      contactEmail,
      contactPhone,
      contactWhatsapp,
      socialLinks,
      bankDetails,
      paymentInstructions,
      aiSettings,
    } = body;

    // Get or create settings
    let settings = await PlatformSettings.findOne();
    if (!settings) {
      settings = new PlatformSettings({ contactEmail: contactEmail || '[email protected]' });
    }

    // Update contact settings if provided
    if (contactEmail !== undefined) {
      // Validate email format
      const emailRegex = /^\S+@\S+\.\S+$/;
      if (!emailRegex.test(contactEmail)) {
        return NextResponse.json(
          { error: 'Please enter a valid email address' },
          { status: 400 }
        );
      }
      settings.
GET function · typescript · L44-L254 (211 LOC)
src/app/api/super-admin/stats/route.ts
export async function GET() {
  try {
    // Verify super admin
    const cookieStore = await cookies();
    const token = cookieStore.get('super-admin-token')?.value;

    if (!token) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const session = await verifySuperAdminToken(token);
    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();

    // Get date ranges
    const now = new Date();
    const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const startOfWeek = new Date(now);
    startOfWeek.setDate(now.getDate() - 7);
    const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
    const startOfLastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);

    // Optimized: Use $facet to combine multiple counts in single query per collection
    const [tenantStats, userStats, postStats, recentTenants, recentPosts, topTenantsBy
POST function · typescript · L8-L141 (134 LOC)
src/app/api/super-admin/tenants/create/route.ts
export async function POST(request: NextRequest) {
  try {
    // Verify super admin
    const cookieStore = await cookies();
    const token = cookieStore.get('super-admin-token')?.value;

    if (!token) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const session = await verifySuperAdminToken(token);
    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();

    const body = await request.json();
    const { name, slug, plan, ownerEmail } = body;

    // Validate required fields
    if (!name || !slug || !ownerEmail) {
      return NextResponse.json(
        { error: 'Name, slug, and owner email are required' },
        { status: 400 }
      );
    }

    // Validate slug format
    const slugRegex = /^[a-z0-9-]+$/;
    if (!slugRegex.test(slug)) {
      return NextResponse.json(
        { error: 'Slug can only contain lowercase letters, numbers, and hyphens' },
        { st
GET function · typescript · L9-L188 (180 LOC)
src/app/api/super-admin/tenants/[id]/route.ts
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const cookieStore = await cookies();
    const token = cookieStore.get('super-admin-token')?.value;

    if (!token) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const session = await verifySuperAdminToken(token);
    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();
    const { id } = await params;

    // Validate ObjectId
    if (!mongoose.Types.ObjectId.isValid(id)) {
      return NextResponse.json({ error: 'Invalid tenant ID' }, { status: 400 });
    }

    // Single aggregation to get all data at once
    const [result] = await Tenant.aggregate([
      { $match: { _id: new mongoose.Types.ObjectId(id) } },
      {
        $lookup: {
          from: 'users',
          let: { tenantId: '$_id', ownerId: '$ownerId' },
          pipeline: [
            {
  
PATCH function · typescript · L191-L279 (89 LOC)
src/app/api/super-admin/tenants/[id]/route.ts
export async function PATCH(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const cookieStore = await cookies();
    const token = cookieStore.get('super-admin-token')?.value;

    if (!token) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const session = await verifySuperAdminToken(token);
    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();
    const { id } = await params;

    // Validate ObjectId
    if (!mongoose.Types.ObjectId.isValid(id)) {
      return NextResponse.json({ error: 'Invalid tenant ID' }, { status: 400 });
    }

    const body = await request.json();

    const tenant = await Tenant.findById(id);

    if (!tenant) {
      return NextResponse.json({ error: 'Tenant not found' }, { status: 404 });
    }

    // Update allowed fields using set() method for type safety
    if (body.name !== undefined) tenant.name 
Repobility · code-quality intelligence platform · https://repobility.com
DELETE function · typescript · L282-L329 (48 LOC)
src/app/api/super-admin/tenants/[id]/route.ts
export async function DELETE(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const cookieStore = await cookies();
    const token = cookieStore.get('super-admin-token')?.value;

    if (!token) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const session = await verifySuperAdminToken(token);
    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();
    const { id } = await params;

    // Validate ObjectId
    if (!mongoose.Types.ObjectId.isValid(id)) {
      return NextResponse.json({ error: 'Invalid tenant ID' }, { status: 400 });
    }

    const tenant = await Tenant.findById(id);

    if (!tenant) {
      return NextResponse.json({ error: 'Tenant not found' }, { status: 404 });
    }

    // Soft delete - change status to deleted
    tenant.status = 'deleted';
    await tenant.save();

    return NextResponse.json({
      success:
GET function · typescript · L38-L215 (178 LOC)
src/app/api/super-admin/tenants/route.ts
export async function GET(request: NextRequest) {
  try {
    // Verify super admin
    const cookieStore = await cookies();
    const token = cookieStore.get('super-admin-token')?.value;

    if (!token) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const session = await verifySuperAdminToken(token);
    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();

    // Parse query params
    const searchParams = request.nextUrl.searchParams;
    const page = Math.max(1, parseInt(searchParams.get('page') || '1'));
    const limit = Math.min(100, Math.max(1, parseInt(searchParams.get('limit') || '10')));
    const search = searchParams.get('search')?.trim() || '';
    const status = searchParams.get('status') || '';
    const plan = searchParams.get('plan') || '';
    const sortBy = searchParams.get('sortBy') || 'createdAt';
    const sortOrder = searchParams.get('sortOrder') === '
verifySuperAdmin function · typescript · L9-L26 (18 LOC)
src/app/api/super-admin/users/route.ts
async function verifySuperAdmin(request: NextRequest) {
  const cookieStore = await cookies();
  const token = cookieStore.get('super-admin-token')?.value;

  if (!token) {
    return null;
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET) as any;
    if (decoded.type !== 'super-admin') {
      return null;
    }
    return decoded;
  } catch {
    return null;
  }
}
GET function · typescript · L28-L53 (26 LOC)
src/app/api/super-admin/users/route.ts
export async function GET(request: NextRequest) {
  try {
    const admin = await verifySuperAdmin(request);
    if (!admin) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    await connectDB();

    const users = await User.find()
      .populate('tenantId', 'name slug')
      .sort({ createdAt: -1 })
      .lean();

    return NextResponse.json({
      success: true,
      data: users,
    });
  } catch (error) {
    console.error('Error fetching users:', error);
    return NextResponse.json(
      { error: 'Failed to fetch users' },
      { status: 500 }
    );
  }
}
GET function · typescript · L4-L54 (51 LOC)
src/app/api/tenants/check-slug/route.ts
export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url);
    const slug = searchParams.get('slug');

    if (!slug) {
      return NextResponse.json(
        { error: 'Slug parameter is required' },
        { status: 400 }
      );
    }

    // Validate slug format
    const slugRegex = /^[a-z0-9-]+$/;
    if (!slugRegex.test(slug.toLowerCase())) {
      return NextResponse.json({
        available: false,
        message: 'Slug can only contain lowercase letters, numbers, and hyphens',
      });
    }

    // Check minimum length
    if (slug.length < 3) {
      return NextResponse.json({
        available: false,
        message: 'Slug must be at least 3 characters',
      });
    }

    // Check maximum length
    if (slug.length > 30) {
      return NextResponse.json({
        available: false,
        message: 'Slug cannot exceed 30 characters',
      });
    }

    const available = await isSlugAvailable(slug);

    return Next
POST function · typescript · L13-L194 (182 LOC)
src/app/api/tenants/create/route.ts
export async function POST(request: NextRequest) {
  try {
    // Check authentication
    const session = await getServerSession(authOptions);

    if (!session?.user?.email) {
      return NextResponse.json(
        { error: 'You must be logged in to create a blog' },
        { status: 401 }
      );
    }

    const body = await request.json();
    const { name, slug, plan: planSlug = 'free' } = body;

    // Validate required fields
    if (!name || !slug) {
      return NextResponse.json(
        { error: 'Blog name and URL are required' },
        { status: 400 }
      );
    }

    // Validate slug format
    const slugRegex = /^[a-z0-9-]+$/;
    if (!slugRegex.test(slug.toLowerCase())) {
      return NextResponse.json(
        { error: 'URL can only contain lowercase letters, numbers, and hyphens' },
        { status: 400 }
      );
    }

    // Check slug length
    if (slug.length < 3 || slug.length > 30) {
      return NextResponse.json(
        { error: 'URL must be betwee
POST function · typescript · L12-L301 (290 LOC)
src/app/api/tenants/register/route.ts
export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const {
      name,
      slug,
      email,
      ownerName,
      password,
      phone,
      countryCode,
      address,
      city,
      country,
      plan: selectedPlanSlug,
      couponId,
      couponCode,
      discountAmount,
      finalPrice,
    } = body;

    // Validate required fields
    if (!name || !slug || !email || !ownerName) {
      return NextResponse.json(
        { error: 'Name, slug, email, and owner name are required' },
        { status: 400 }
      );
    }

    // Password is always required for registration
    if (!password) {
      return NextResponse.json(
        { error: 'Password is required' },
        { status: 400 }
      );
    }

    // Validate password length
    if (password && password.length < 6) {
      return NextResponse.json(
        { error: 'Password must be at least 6 characters' },
        { status: 400 }
      );
    }

    // V
processImage function · typescript · L13-L162 (150 LOC)
src/app/api/upload/route.ts
async function processImage(
  imageBuffer: Buffer,
  branding: {
    enabled: boolean;
    type: 'text' | 'image';
    text?: string;
    imageUrl?: string;
    position: string;
    opacity: number;
    backgroundColor?: string;
    textColor?: string;
  }
): Promise<Buffer> {
  if (!branding.enabled) {
    return imageBuffer;
  }

  // Dynamic import for sharp to avoid build issues
  let sharp: any;
  try {
    sharp = (await import('sharp')).default;
  } catch (err) {
    console.error('Failed to load sharp library:', err);
    return imageBuffer; // Return original image if sharp fails to load
  }

  try {
    const image = sharp(imageBuffer);
    const metadata = await image.metadata();
    const width = metadata.width || 800;
    const height = metadata.height || 600;

    // Calculate watermark position
    let gravity: 'southeast' | 'southwest' | 'northeast' | 'northwest' = 'southeast';

    switch (branding.position) {
      case 'bottom-right':
        gravity = 'southeast';
Repobility · open methodology · https://repobility.com/research/
POST function · typescript · L164-L302 (139 LOC)
src/app/api/upload/route.ts
export async function POST(request: NextRequest) {
  try {
    // Check authentication
    const session = await getServerSession(authOptions);
    const isAdmin = session?.user?.role === 'admin';
    const isEditor = session?.user?.role === 'editor';
    const isAuthor = session?.user?.role === 'author' && session?.user?.canPost;

    if (!session || (!isAdmin && !isEditor && !isAuthor)) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    // Check if API key is configured
    if (!IMGBB_API_KEY) {
      return NextResponse.json(
        { error: 'ImgBB API key not configured' },
        { status: 500 }
      );
    }

    // Get the form data
    const formData = await request.formData();
    const file = formData.get('image') as File | null;
    const skipWatermark = formData.get('skipWatermark') === 'true'; // For avatar uploads

    if (!file) {
      return NextResponse.json({ error: 'No image provided' }, { status: 400 });
    }

    // Valida
GET function · typescript · L10-L152 (143 LOC)
src/app/api/user/tenant/route.ts
export async function GET(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);

    if (!session?.user?.email) {
      return NextResponse.json({ success: false, data: null });
    }

    await connectDB();

    const email = session.user.email.toLowerCase();

    // Check if user is an author (logged in via credentials)
    // The session will have tenantId set directly from auth
    if (session.user.role === 'author' && session.user.tenantId) {
      const tenant = await Tenant.findById(session.user.tenantId).lean();
      if (tenant && (tenant as any).status === 'active') {
        return NextResponse.json({
          success: true,
          data: {
            id: (tenant as any)._id.toString(),
            name: (tenant as any).name,
            slug: (tenant as any).slug,
          },
        });
      }
    }

    // Also check Author model for authors who might not have tenantId in session
    const author = await Author.findOne({ email });
GET function · typescript · L7-L40 (34 LOC)
src/app/api/verify-domain/route.ts
export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url);
    const domain = searchParams.get('domain');

    if (!domain) {
      return new NextResponse('Missing domain', { status: 400 });
    }

    // Allow main platform domains
    const platformDomain = process.env.NEXT_PUBLIC_PLATFORM_DOMAIN || 'launchory.org';
    if (domain === platformDomain || domain === `www.${platformDomain}`) {
      return new NextResponse('OK', { status: 200 });
    }

    // Check if this is a verified custom domain
    await connectDB();
    const tenant = await Tenant.findOne({
      customDomain: domain.toLowerCase(),
      customDomainStatus: 'verified',
      status: 'active',
    }).lean();

    if (tenant) {
      return new NextResponse('OK', { status: 200 });
    }

    // Domain not found or not verified
    return new NextResponse('Domain not allowed', { status: 404 });
  } catch (error) {
    console.error('Error verifying domain:', error);
AuthorsPage function · typescript · L12-L41 (30 LOC)
src/app/authors/page.tsx
export default async function AuthorsPage() {
  const authors = await getAllAuthors();

  return (
    <div className="container mx-auto px-4 py-12">
      {/* Header */}
      <div className="mb-12 text-center">
        <h1 className="mb-4 text-4xl font-bold text-gray-900 dark:text-white">
          Our Authors
        </h1>
        <p className="text-lg text-gray-600 dark:text-gray-400">
          Meet the talented writers behind our content
        </p>
      </div>

      {/* Authors Grid */}
      {authors.length > 0 ? (
        <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
          {authors.map((author) => (
            <AuthorCard key={author._id} author={author} />
          ))}
        </div>
      ) : (
        <div className="py-12 text-center">
          <p className="text-gray-500 dark:text-gray-400">No authors yet.</p>
        </div>
      )}
    </div>
  );
}
generateMetadata function · typescript · L14-L33 (20 LOC)
src/app/authors/[slug]/page.tsx
export async function generateMetadata({ params }: AuthorPageProps): Promise<Metadata> {
  const { slug } = await params;
  const author = await getAuthorBySlug(slug);

  if (!author) {
    return {
      title: 'Author Not Found',
    };
  }

  return {
    title: author.name,
    description: author.bio,
    openGraph: {
      title: author.name,
      description: author.bio,
      images: [{ url: author.avatar }],
    },
  };
}
AuthorPage function · typescript · L35-L61 (27 LOC)
src/app/authors/[slug]/page.tsx
export default async function AuthorPage({ params }: AuthorPageProps) {
  const { slug } = await params;
  const author = await getAuthorBySlug(slug);

  if (!author) {
    notFound();
  }

  const posts = await getPostsByAuthor(author.slug);

  return (
    <div className="container mx-auto px-4 py-12">
      <div className="mx-auto max-w-5xl">
        {/* Author Bio */}
        <AuthorBio author={author} postCount={posts.length} />

        {/* Author's Posts */}
        <section>
          <h2 className="mb-8 text-2xl font-bold text-gray-900 dark:text-white">
            Posts by {author.name}
          </h2>
          <PostList posts={posts} columns={2} />
        </section>
      </div>
    </div>
  );
}
BlogLoading function · typescript · L1-L27 (27 LOC)
src/app/blog/loading.tsx
export default function BlogLoading() {
  return (
    <div className="container mx-auto px-4 py-12">
      <div className="mb-8 animate-pulse">
        <div className="h-10 w-48 bg-gray-200 dark:bg-gray-700 rounded mb-4" />
        <div className="h-4 w-96 bg-gray-200 dark:bg-gray-700 rounded" />
      </div>

      <div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
        {[...Array(6)].map((_, i) => (
          <div key={i} className="animate-pulse rounded-xl bg-white dark:bg-gray-800 overflow-hidden shadow-sm">
            <div className="h-48 bg-gray-200 dark:bg-gray-700" />
            <div className="p-6">
              <div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded mb-3" />
              <div className="h-6 w-full bg-gray-200 dark:bg-gray-700 rounded mb-2" />
              <div className="h-4 w-3/4 bg-gray-200 dark:bg-gray-700 rounded mb-4" />
              <div className="flex gap-2">
                <div className="h-6 w-6 bg-gray-200 dark:bg-gray-700 
generateBlogListingSchema function · typescript · L160-L188 (29 LOC)
src/app/blog/page.tsx
function generateBlogListingSchema() {
  return {
    '@context': 'https://schema.org',
    '@type': 'Blog',
    name: 'Launchory Blog',
    description: 'Expert tips on blogging, SEO, content marketing, and monetization strategies.',
    url: `${siteUrl}/blog`,
    publisher: {
      '@type': 'Organization',
      name: 'Launchory',
      logo: {
        '@type': 'ImageObject',
        url: `${siteUrl}/logo.png`,
      },
    },
    blogPost: blogPosts.map((post) => ({
      '@type': 'BlogPosting',
      headline: post.title,
      description: post.excerpt,
      url: `${siteUrl}/blog/${post.slug}`,
      datePublished: post.publishedAt,
      author: {
        '@type': 'Person',
        name: post.author.name,
      },
      image: post.image,
    })),
  };
}
Hi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
BlogPage function · typescript · L190-L461 (272 LOC)
src/app/blog/page.tsx
export default function BlogPage() {
  const featuredPost = blogPosts.find(post => post.featured);
  const regularPosts = blogPosts.filter(post => !post.featured);
  const blogListingSchema = generateBlogListingSchema();

  return (
    <>
      {/* JSON-LD Structured Data */}
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(blogListingSchema) }}
      />

      <main className="min-h-screen bg-white dark:bg-gray-950">
        {/* Navigation */}
        <nav className="fixed top-0 left-0 right-0 z-50 border-b border-gray-200/50 dark:border-white/10 bg-white/80 dark:bg-gray-950/80 backdrop-blur-xl">
          <div className="container mx-auto px-4">
            <div className="flex items-center justify-between h-16">
              <Link href="/" className="flex items-center gap-2">
                <div className="w-8 h-8 bg-gradient-to-br from-indigo-500 to-purple-600 rounded-lg flex items-center justify-center">
                
CopyLinkButton function · typescript · L7-L23 (17 LOC)
src/app/blog/[slug]/CopyLinkButton.tsx
export default function CopyLinkButton({ url }: CopyLinkButtonProps) {
  const handleCopy = () => {
    navigator.clipboard?.writeText(url);
  };

  return (
    <button
      onClick={handleCopy}
      className="flex items-center gap-2 px-4 py-2 bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"
    >
      <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
      </svg>
      Copy Link
    </button>
  );
}
Loading function · typescript · L1-L26 (26 LOC)
src/app/blog/[slug]/loading.tsx
export default function Loading() {
  return (
    <div className="container mx-auto px-4 py-12">
      <div className="mx-auto max-w-3xl">
        {/* Header skeleton */}
        <div className="mb-8 animate-pulse">
          <div className="mb-4 h-4 w-24 rounded bg-gray-200 dark:bg-gray-700" />
          <div className="mb-4 h-10 w-3/4 rounded bg-gray-200 dark:bg-gray-700" />
          <div className="h-6 w-full rounded bg-gray-200 dark:bg-gray-700" />
        </div>

        {/* Image skeleton */}
        <div className="mb-8 aspect-video w-full animate-pulse rounded-xl bg-gray-200 dark:bg-gray-700" />

        {/* Content skeleton */}
        <div className="space-y-4 animate-pulse">
          <div className="h-4 w-full rounded bg-gray-200 dark:bg-gray-700" />
          <div className="h-4 w-5/6 rounded bg-gray-200 dark:bg-gray-700" />
          <div className="h-4 w-4/6 rounded bg-gray-200 dark:bg-gray-700" />
          <div className="h-4 w-full rounded bg-gray-200 dark:bg-gray-7
NotFound function · typescript · L3-L22 (20 LOC)
src/app/blog/[slug]/not-found.tsx
export default function NotFound() {
  return (
    <div className="container mx-auto px-4 py-12">
      <div className="mx-auto max-w-2xl text-center">
        <h1 className="mb-4 text-4xl font-bold text-gray-900 dark:text-white">
          Post Not Found
        </h1>
        <p className="mb-8 text-gray-600 dark:text-gray-400">
          The blog post you&apos;re looking for doesn&apos;t exist or has been removed.
        </p>
        <Link
          href="/blog"
          className="inline-block rounded-lg bg-primary-600 px-6 py-3 font-medium text-white hover:bg-primary-700"
        >
          Browse All Posts
        </Link>
      </div>
    </div>
  );
}
generateMetadata function · typescript · L432-L475 (44 LOC)
src/app/blog/[slug]/page.tsx
export async function generateMetadata({ params }: BlogPostPageProps): Promise<Metadata> {
  const { slug } = await params;
  const post = blogPosts.find(p => p.slug === slug);

  if (!post) {
    return {
      title: 'Post Not Found - Launchory Blog',
    };
  }

  return {
    title: `${post.title} | Launchory Blog`,
    description: post.excerpt,
    keywords: post.keywords,
    authors: [{ name: post.author.name }],
    openGraph: {
      title: post.title,
      description: post.excerpt,
      url: `${siteUrl}/blog/${post.slug}`,
      siteName: 'Launchory',
      type: 'article',
      publishedTime: post.publishedAt,
      modifiedTime: post.modifiedAt,
      authors: [post.author.name],
      images: [
        {
          url: post.image,
          width: 1200,
          height: 630,
          alt: post.imageAlt,
        },
      ],
    },
    twitter: {
      card: 'summary_large_image',
      title: post.title,
      description: post.excerpt,
      images: [post.image],
  
generateArticleSchema function · typescript · L478-L509 (32 LOC)
src/app/blog/[slug]/page.tsx
function generateArticleSchema(post: typeof blogPosts[0]) {
  return {
    '@context': 'https://schema.org',
    '@type': 'BlogPosting',
    headline: post.title,
    description: post.excerpt,
    image: post.image,
    datePublished: post.publishedAt,
    dateModified: post.modifiedAt,
    author: {
      '@type': 'Person',
      name: post.author.name,
      jobTitle: post.author.role,
      description: post.author.bio,
    },
    publisher: {
      '@type': 'Organization',
      name: 'Launchory',
      logo: {
        '@type': 'ImageObject',
        url: `${siteUrl}/logo.png`,
      },
    },
    mainEntityOfPage: {
      '@type': 'WebPage',
      '@id': `${siteUrl}/blog/${post.slug}`,
    },
    keywords: post.keywords.join(', '),
    articleSection: post.category,
    wordCount: post.content.split(/\s+/).length,
  };
}
generateBreadcrumbSchema function · typescript · L512-L537 (26 LOC)
src/app/blog/[slug]/page.tsx
function generateBreadcrumbSchema(post: typeof blogPosts[0]) {
  return {
    '@context': 'https://schema.org',
    '@type': 'BreadcrumbList',
    itemListElement: [
      {
        '@type': 'ListItem',
        position: 1,
        name: 'Home',
        item: siteUrl,
      },
      {
        '@type': 'ListItem',
        position: 2,
        name: 'Blog',
        item: `${siteUrl}/blog`,
      },
      {
        '@type': 'ListItem',
        position: 3,
        name: post.title,
        item: `${siteUrl}/blog/${post.slug}`,
      },
    ],
  };
}
BlogPostPage function · typescript · L539-L880 (342 LOC)
src/app/blog/[slug]/page.tsx
export default async function BlogPostPage({ params }: BlogPostPageProps) {
  const { slug } = await params;
  const post = blogPosts.find(p => p.slug === slug);

  if (!post) {
    notFound();
  }

  // Get related posts (same category, excluding current)
  const relatedPosts = blogPosts
    .filter(p => p.category === post.category && p.slug !== post.slug)
    .slice(0, 3);

  // If not enough related posts in same category, fill with other posts
  if (relatedPosts.length < 3) {
    const otherPosts = blogPosts
      .filter(p => p.slug !== post.slug && !relatedPosts.includes(p))
      .slice(0, 3 - relatedPosts.length);
    relatedPosts.push(...otherPosts);
  }

  const articleSchema = generateArticleSchema(post);
  const breadcrumbSchema = generateBreadcrumbSchema(post);

  return (
    <>
      {/* JSON-LD Structured Data */}
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(articleSchema) }}
      />
      <script
        t
Powered by Repobility — scan your code at https://repobility.com
getTenantFromCustomDomain function · typescript · L15-L26 (12 LOC)
src/app/cd/blog/page.tsx
async function getTenantFromCustomDomain() {
  const headersList = await headers();
  const customDomain = headersList.get('x-custom-domain');
  if (!customDomain) return null;

  await connectDB();
  return await Tenant.findOne({
    customDomain: customDomain.toLowerCase(),
    customDomainStatus: 'verified',
    status: 'active',
  }).lean();
}
CustomDomainBlogPage function · typescript · L32-L170 (139 LOC)
src/app/cd/blog/page.tsx
export default async function CustomDomainBlogPage({ searchParams }: BlogPageProps) {
  const tenant = await getTenantFromCustomDomain();
  const { category, page } = await searchParams;

  if (!tenant) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-950">
        <p className="text-gray-600 dark:text-gray-400">Domain not configured</p>
      </div>
    );
  }

  const tenantId = tenant._id.toString();
  await connectDB();

  const settings = await Settings.findOne({ tenantId }).lean();
  const postsPerPage = settings?.postsPerPage || 10;
  const currentPage = Math.max(1, parseInt(page || '1', 10));

  const [paginatedResult, categoriesData] = await Promise.all([
    getPaginatedPosts(tenantId, { page: currentPage, limit: postsPerPage, category }),
    Category.find({ tenantId }).sort({ name: 1 }).lean(),
  ]);

  const posts = paginatedResult.posts;
  const totalPages = paginatedResult.totalPages;
  const categories = categori
getTenantFromCustomDomain function · typescript · L16-L27 (12 LOC)
src/app/cd/blog/[slug]/page.tsx
async function getTenantFromCustomDomain() {
  const headersList = await headers();
  const customDomain = headersList.get('x-custom-domain');
  if (!customDomain) return null;

  await connectDB();
  return await Tenant.findOne({
    customDomain: customDomain.toLowerCase(),
    customDomainStatus: 'verified',
    status: 'active',
  }).lean();
}
generateMetadata function · typescript · L33-L46 (14 LOC)
src/app/cd/blog/[slug]/page.tsx
export async function generateMetadata({ params }: PostPageProps): Promise<Metadata> {
  const { slug } = await params;
  const tenant = await getTenantFromCustomDomain();
  if (!tenant) return {};

  await connectDB();
  const post = await Post.findOne({ tenantId: tenant._id, slug, published: true }).lean();
  if (!post) return {};

  return {
    title: post.title,
    description: post.description,
  };
}
CustomDomainPostPage function · typescript · L48-L230 (183 LOC)
src/app/cd/blog/[slug]/page.tsx
export default async function CustomDomainPostPage({ params }: PostPageProps) {
  const { slug } = await params;
  const tenant = await getTenantFromCustomDomain();

  if (!tenant) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-950">
        <p className="text-gray-600 dark:text-gray-400">Domain not configured</p>
      </div>
    );
  }

  await connectDB();

  const post = await Post.findOne({
    tenantId: tenant._id,
    slug,
    published: true,
  }).populate('author', 'name image').lean();

  if (!post) {
    notFound();
  }

  // Increment view count
  await Post.findByIdAndUpdate(post._id, { $inc: { views: 1 } });

  const settings = await Settings.findOne({ tenantId: tenant._id }).lean();
  const siteName = settings?.siteName || tenant.settings?.siteName || tenant.name;
  const siteLogo = settings?.siteLogo || '';
  const primaryColor = settings?.primaryColor || '#6366f1';
  const accentColor = settings?.accentColor 
getTenantFromCustomDomain function · typescript · L18-L29 (12 LOC)
src/app/cd/[pageSlug]/page.tsx
async function getTenantFromCustomDomain() {
  const headersList = await headers();
  const customDomain = headersList.get('x-custom-domain');
  if (!customDomain) return null;

  await connectDB();
  return await Tenant.findOne({
    customDomain: customDomain.toLowerCase(),
    customDomainStatus: 'verified',
    status: 'active',
  }).lean();
}
generateMetadata function · typescript · L35-L56 (22 LOC)
src/app/cd/[pageSlug]/page.tsx
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
  const { pageSlug } = await params;

  if (RESERVED_SLUGS.includes(pageSlug.toLowerCase())) {
    return {};
  }

  const tenant = await getTenantFromCustomDomain();
  if (!tenant) return {};

  await connectDB();
  const page = await Page.findOne({ tenantId: tenant._id, slug: pageSlug, published: true }).lean() as any;
  if (!page) return {};

  const settings = await Settings.findOne({ tenantId: tenant._id }).lean();
  const siteName = settings?.siteName || tenant.name;

  return {
    title: page.seoTitle || `${page.title} | ${siteName}`,
    description: page.seoDescription || page.heroSubtitle || `${page.title} - ${siteName}`,
  };
}
CustomDomainPage function · typescript · L58-L354 (297 LOC)
src/app/cd/[pageSlug]/page.tsx
export default async function CustomDomainPage({ params }: PageProps) {
  const { pageSlug } = await params;

  if (RESERVED_SLUGS.includes(pageSlug.toLowerCase())) {
    notFound();
  }

  const tenant = await getTenantFromCustomDomain();
  if (!tenant) {
    notFound();
  }

  await connectDB();

  const page = await Page.findOne({
    tenantId: tenant._id,
    slug: pageSlug,
    published: true,
  }).lean() as any;

  if (!page) {
    notFound();
  }

  const settings = await Settings.findOne({ tenantId: tenant._id }).lean();
  const siteName = settings?.siteName || tenant.settings?.siteName || tenant.name;
  const siteLogo = settings?.siteLogo || '';
  const primaryColor = settings?.primaryColor || '#6366f1';
  const accentColor = settings?.accentColor || '#8b5cf6';

  // Get pages for navbar
  const navPages = await Page.find({
    tenantId: tenant._id,
    published: true,
    showInNavbar: true,
  }).sort({ navbarOrder: 1 }).lean();

  // Get categories for navbar
  const categ
Repobility · code-quality intelligence platform · https://repobility.com
getTenantFromCustomDomain function · typescript · L20-L36 (17 LOC)
src/app/cd/page.tsx
async function getTenantFromCustomDomain() {
  const headersList = await headers();
  const customDomain = headersList.get('x-custom-domain');

  if (!customDomain) {
    return null;
  }

  await connectDB();
  const tenant = await Tenant.findOne({
    customDomain: customDomain.toLowerCase(),
    customDomainStatus: 'verified',
    status: 'active',
  }).lean();

  return tenant;
}
generateMetadata function · typescript · L38-L61 (24 LOC)
src/app/cd/page.tsx
export async function generateMetadata(): Promise<Metadata> {
  const tenant = await getTenantFromCustomDomain();
  if (!tenant) return {};

  await connectDB();
  const settings = await Settings.findOne({ tenantId: tenant._id }).lean();

  const siteName = settings?.siteName || tenant.settings?.siteName || tenant.name;
  const seoDescription = settings?.seoDescription || settings?.siteDescription || 'Welcome to our blog';
  const seoKeywords = settings?.seoKeywords || [];
  const ogImage = settings?.ogImage || '';

  return {
    title: siteName,
    description: seoDescription,
    keywords: seoKeywords.join(', '),
    openGraph: {
      title: siteName,
      description: seoDescription,
      images: ogImage ? [ogImage] : [],
      siteName: siteName,
    },
  };
}
CustomDomainHomePage function · typescript · L67-L409 (343 LOC)
src/app/cd/page.tsx
export default async function CustomDomainHomePage({ searchParams }: CustomDomainPageProps) {
  const tenant = await getTenantFromCustomDomain();
  const { page } = await searchParams;

  if (!tenant) {
    const headersList = await headers();
    const customDomain = headersList.get('x-custom-domain') || 'Unknown domain';

    return (
      <div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-950">
        <div className="text-center p-8 max-w-md">
          <div className="w-16 h-16 rounded-full bg-red-100 dark:bg-red-900/30 flex items-center justify-center mx-auto mb-4">
            <svg className="w-8 h-8 text-red-600 dark:text-red-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
            </svg>
          </div>
     
‹ prevpage 3 / 7next ›