Response wall build out
This commit is contained in:
@@ -291,7 +291,7 @@ async function getResponseStats(req, res) {
|
||||
|
||||
// Get all approved responses for this campaign
|
||||
const responses = await nocodbService.getRepresentativeResponses({
|
||||
where: `(Campaign Slug,eq,${slug}),(Status,eq,approved)`
|
||||
where: `(Campaign Slug,eq,${slug})~and(Status,eq,approved)`
|
||||
});
|
||||
|
||||
// Calculate stats
|
||||
@@ -323,43 +323,91 @@ async function getResponseStats(req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
// Admin functions
|
||||
// Admin and campaign owner functions
|
||||
|
||||
/**
|
||||
* Get all responses (admin only - includes pending/rejected)
|
||||
* Get all responses (admin or campaign owners - includes pending/rejected)
|
||||
* Campaign owners only see responses to their own campaigns
|
||||
* @param {Object} req - Express request object
|
||||
* @param {Object} res - Express response object
|
||||
*/
|
||||
async function getAdminResponses(req, res) {
|
||||
try {
|
||||
const { status = 'all', offset = 0, limit = 50 } = req.query;
|
||||
const { status = 'all', campaign_slug = '', offset = 0, limit = 50 } = req.query;
|
||||
|
||||
console.log(`Admin fetching responses with status filter: ${status}`);
|
||||
console.log(`User fetching responses with status filter: ${status}, campaign: ${campaign_slug}`);
|
||||
|
||||
const isAdmin = (req.user && req.user.isAdmin) || req.session?.isAdmin || false;
|
||||
const sessionUserId = req.user?.id ?? req.session?.userId ?? null;
|
||||
const sessionUserEmail = req.user?.email ?? req.session?.userEmail ?? null;
|
||||
|
||||
// If not admin, we need to filter by campaign ownership
|
||||
let campaignsToFilter = [];
|
||||
if (!isAdmin) {
|
||||
// Get all campaigns owned by this user
|
||||
const allCampaigns = await nocodbService.getAllCampaigns();
|
||||
|
||||
campaignsToFilter = allCampaigns.filter(campaign => {
|
||||
const createdById = campaign['Created By User ID'] ?? campaign.created_by_user_id ?? null;
|
||||
const createdByEmail = campaign['Created By User Email'] ?? campaign.created_by_user_email ?? null;
|
||||
|
||||
return (
|
||||
(createdById != null && sessionUserId != null && String(createdById) === String(sessionUserId)) ||
|
||||
(createdByEmail && sessionUserEmail && String(createdByEmail).toLowerCase() === String(sessionUserEmail).toLowerCase())
|
||||
);
|
||||
});
|
||||
|
||||
console.log(`User owns ${campaignsToFilter.length} campaigns out of ${allCampaigns.length} total`);
|
||||
}
|
||||
|
||||
let whereConditions = [];
|
||||
|
||||
// Filter by status
|
||||
if (status !== 'all') {
|
||||
whereConditions.push(`(Status,eq,${status})`);
|
||||
}
|
||||
|
||||
// Filter by campaign slug if provided
|
||||
if (campaign_slug) {
|
||||
const slugCondition = `(Campaign Slug,eq,${campaign_slug})`;
|
||||
if (whereConditions.length > 0) {
|
||||
whereConditions[0] += `~and${slugCondition}`;
|
||||
} else {
|
||||
whereConditions.push(slugCondition);
|
||||
}
|
||||
}
|
||||
|
||||
const responses = await nocodbService.getRepresentativeResponses({
|
||||
where: whereConditions.join(','),
|
||||
where: whereConditions.length > 0 ? whereConditions[0] : undefined,
|
||||
sort: '-CreatedAt',
|
||||
offset: parseInt(offset),
|
||||
limit: parseInt(limit)
|
||||
});
|
||||
|
||||
console.log(`Admin found ${responses.length} total responses`);
|
||||
if (responses.length > 0) {
|
||||
console.log('Response statuses:', responses.map(r => `ID:${r.id} Status:${r.status}`).join(', '));
|
||||
console.log(`Found ${responses.length} total responses before filtering`);
|
||||
|
||||
// Filter responses by campaign ownership if not admin
|
||||
let filteredResponses = responses;
|
||||
if (!isAdmin && campaignsToFilter.length > 0) {
|
||||
const ownedCampaignSlugs = campaignsToFilter.map(c => c['Campaign Slug'] || c.slug);
|
||||
filteredResponses = responses.filter(r => ownedCampaignSlugs.includes(r.campaign_slug));
|
||||
console.log(`After ownership filter: ${filteredResponses.length} responses`);
|
||||
} else if (!isAdmin) {
|
||||
// User owns no campaigns, return empty
|
||||
filteredResponses = [];
|
||||
}
|
||||
|
||||
if (filteredResponses.length > 0) {
|
||||
console.log('Response statuses:', filteredResponses.map(r => `ID:${r.id} Status:${r.status}`).join(', '));
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
responses,
|
||||
responses: filteredResponses,
|
||||
pagination: {
|
||||
offset: parseInt(offset),
|
||||
limit: parseInt(limit),
|
||||
hasMore: responses.length === parseInt(limit)
|
||||
hasMore: filteredResponses.length === parseInt(limit)
|
||||
}
|
||||
});
|
||||
|
||||
@@ -370,7 +418,7 @@ async function getAdminResponses(req, res) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update response status (admin only)
|
||||
* Update response status (admin or campaign owner)
|
||||
* @param {Object} req - Express request object
|
||||
* @param {Object} res - Express response object
|
||||
*/
|
||||
@@ -385,6 +433,38 @@ async function updateResponseStatus(req, res) {
|
||||
return res.status(400).json({ error: 'Invalid status' });
|
||||
}
|
||||
|
||||
// Get the response to check campaign ownership
|
||||
const response = await nocodbService.getRepresentativeResponseById(id);
|
||||
if (!response) {
|
||||
return res.status(404).json({ error: 'Response not found' });
|
||||
}
|
||||
|
||||
// Get campaign to check ownership
|
||||
const campaignId = response.campaign_id;
|
||||
const campaign = await nocodbService.getCampaignById(campaignId);
|
||||
if (!campaign) {
|
||||
return res.status(404).json({ error: 'Campaign not found' });
|
||||
}
|
||||
|
||||
// Check if user is admin or campaign owner
|
||||
const isAdmin = (req.user && req.user.isAdmin) || req.session?.isAdmin || false;
|
||||
const sessionUserId = req.user?.id ?? req.session?.userId ?? null;
|
||||
const sessionUserEmail = req.user?.email ?? req.session?.userEmail ?? null;
|
||||
|
||||
if (!isAdmin) {
|
||||
const createdById = campaign['Created By User ID'] ?? campaign.created_by_user_id ?? null;
|
||||
const createdByEmail = campaign['Created By User Email'] ?? campaign.created_by_user_email ?? null;
|
||||
|
||||
const ownsCampaign = (
|
||||
(createdById != null && sessionUserId != null && String(createdById) === String(sessionUserId)) ||
|
||||
(createdByEmail && sessionUserEmail && String(createdByEmail).toLowerCase() === String(sessionUserEmail).toLowerCase())
|
||||
);
|
||||
|
||||
if (!ownsCampaign) {
|
||||
return res.status(403).json({ error: 'You can only moderate responses to your own campaigns' });
|
||||
}
|
||||
}
|
||||
|
||||
const updated = await nocodbService.updateRepresentativeResponse(id, { status });
|
||||
console.log('Updated response:', JSON.stringify(updated, null, 2));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user