File size: 5,405 Bytes
7d51e81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// src/controllers/workController.js
import { NextResponse } from "next/server";
import streamifier from "streamifier";
import { connectDB } from "@/lib/db";
import Work from "@/models/Work";
import cloudinary from "@/lib/cloudinary";

/**

 * Login/create user record by (name, usn)

 */
export async function loginOrGetUser(req) {
  try {
    await connectDB();
    const body = await req.json();
    const { name, usn: rawUsn } = body;
    if (!rawUsn || !name) {
      return NextResponse.json({ error: "name and usn required" }, { status: 400 });
    }

    const usn = String(rawUsn).toUpperCase();
    let work = await Work.findOne({ usn });
    if (!work) {
      work = await Work.create({ usn, name, contents: [] });
    }

    return NextResponse.json(work, { status: 200 });
  } catch (err) {
    console.error("loginOrGetUser error:", err);
    return NextResponse.json({ error: String(err) }, { status: 500 });
  }
}

/**

 * Get user record by USN

 */
export async function getWorkByUsn(req) {
  try {
    await connectDB();
    const url = new URL(req.url);
    const rawUsn = url.searchParams.get("usn");
    if (!rawUsn) return NextResponse.json({ error: "usn required" }, { status: 400 });

    const usn = String(rawUsn).toUpperCase();
    const work = await Work.findOne({ usn });
    return NextResponse.json(work || null, { status: 200 });
  } catch (err) {
    console.error("getWorkByUsn error:", err);
    return NextResponse.json({ error: String(err) }, { status: 500 });
  }
}

/**

 * Add a subject

 */
export async function addSubject(req, { params }) {
  try {
    await connectDB();
    const { id } = params;
    const formData = await req.formData();
    const subject = formData.get("subject");
    if (!subject) return NextResponse.json({ error: "subject required" }, { status: 400 });

    const work = await Work.findById(id);
    if (!work) return NextResponse.json({ error: "work not found" }, { status: 404 });

    work.contents.push({ subject, items: [] });
    await work.save();

    const newSubject = work.contents[work.contents.length - 1];
    return NextResponse.json(newSubject, { status: 201 });
  } catch (error) {
    console.error("addSubject error:", error);
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
}

/**

 * Add content under a subject

 */
export async function addContent(req, { params }) {
  try {
    await connectDB();
    const { id, subjectId } = params;
    const body = await req.json();
    const text = body.text ?? "";

    const work = await Work.findById(id);
    if (!work) return NextResponse.json({ error: "work not found" }, { status: 404 });

    const subj = work.contents.id(subjectId);
    if (!subj) return NextResponse.json({ error: "subject not found" }, { status: 404 });

    subj.items.push({ text, files: [] });
    await work.save();

    const newContent = subj.items[subj.items.length - 1];
    return NextResponse.json(newContent, { status: 201 });
  } catch (err) {
    console.error("addContent error:", err);
    return NextResponse.json({ error: String(err) }, { status: 500 });
  }
}

/**

 * Upload an image to a specific content and return updated content

 */
export async function uploadFileToContent(req, { params }) {
  try {
    await connectDB();
    const { id, subjectId, contentId } = params;

    const formData = await req.formData();
    const file = formData.get("file");
    if (!file) return NextResponse.json({ error: "File required" }, { status: 400 });

    const isImage = /^image\/(jpeg|png|gif|webp|jpg)$/.test(file.type);
    if (!isImage) return NextResponse.json({ error: "Only image files are allowed" }, { status: 400 });

    const buffer = Buffer.from(await file.arrayBuffer());

    // Upload image to Cloudinary
    const result = await new Promise((resolve, reject) => {
      const uploadStream = cloudinary.uploader.upload_stream(
        { folder: "work_files", resource_type: "image" },
        (err, res) => (err ? reject(err) : resolve(res))
      );
      streamifier.createReadStream(buffer).pipe(uploadStream);
    });

    if (!result?.secure_url) return NextResponse.json({ error: "Upload failed" }, { status: 500 });

    // Save file in MongoDB under the correct content
    const work = await Work.findById(id);
    if (!work) return NextResponse.json({ error: "Work not found" }, { status: 404 });

    const subject = work.contents.id(subjectId);
    if (!subject) return NextResponse.json({ error: "Subject not found" }, { status: 404 });

    const contentItem = subject.items.id(contentId);
    if (!contentItem) return NextResponse.json({ error: "Content not found" }, { status: 404 });

    contentItem.files.push({
      url: result.secure_url,
      public_id: result.public_id,
      resource_type: result.resource_type,
    });

    await work.save();

    // Return the updated content item with all files (for preview)
    const updatedContent = subject.items.id(contentId);

    return NextResponse.json({
      message: "File uploaded successfully",
      content: updatedContent,
    }, { status: 201 });

  } catch (err) {
    console.error("uploadFileToContent error:", err);
    return NextResponse.json({ error: String(err) }, { status: 500 });
  }
}