From cc2a66367dff2fc803aade9003c1aa1acee7a37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D1=8F?= Date: Sun, 15 Jun 2025 20:39:27 +0300 Subject: [PATCH] votes --- .../routers/kfu-m-24-1/sber_mobile/votes.js | 95 +++++++++++++++---- 1 file changed, 78 insertions(+), 17 deletions(-) diff --git a/server/routers/kfu-m-24-1/sber_mobile/votes.js b/server/routers/kfu-m-24-1/sber_mobile/votes.js index d46df22..9a861da 100644 --- a/server/routers/kfu-m-24-1/sber_mobile/votes.js +++ b/server/routers/kfu-m-24-1/sber_mobile/votes.js @@ -6,39 +6,100 @@ router.get('/votes/:initiative_id', async (req, res) => { const supabase = getSupabaseClient(); const { initiative_id } = req.params; const { data, error } = await supabase.from('votes').select('*').eq('initiative_id', initiative_id); - if (error) return res.status(400).json({ error: error.message }); + if (error) + return res.status(400).json({ error: error.message }); res.json(data); }); // Получить голос пользователя по инициативе -router.get('/votes/:initiative_id/:user_id', async (req, res) => { +router.get('/votes/:initiative_id/user/:user_id', async (req, res) => { const supabase = getSupabaseClient(); const { initiative_id, user_id } = req.params; const { data, error } = await supabase.from('votes').select('*').eq('initiative_id', initiative_id).eq('user_id', user_id).single(); - if (error) return res.status(400).json({ error: error.message }); + if (error) { + console.log(error, '/votes/:initiative_id/:user_id') + console.log(initiative_id, user_id) + return res.status(400).json({ error: error.message }); + } res.json(data); }); -// Получить все голоса по инициативе (через query) -router.get('/votes', async (req, res) => { +// Получить статистику голосов по инициативе +router.get('/votes/stats/:initiative_id', async (req, res) => { const supabase = getSupabaseClient(); - const { initiative_id } = req.query; - if (!initiative_id) return res.status(400).json({ error: 'initiative_id required' }); - const { data, error } = await supabase.from('votes').select('*').eq('initiative_id', initiative_id); - if (error) return res.status(400).json({ error: error.message }); - res.json(data); + const { initiative_id } = req.params; + + const { data, error } = await supabase + .from('votes') + .select('vote_type') + .eq('initiative_id', initiative_id); + console.log(data, error) + if (error) { + console.log('/votes/:initiative_id/stats') + res.status(400).json({ error: error.message }); + } + const stats = { + for: data.filter(vote => vote.vote_type === 'for').length, + against: data.filter(vote => vote.vote_type === 'against').length, + total: data.length + }; + + res.json(stats); }); -// Проголосовать (создать или обновить голос) +// Проголосовать (создать, обновить или удалить голос) router.post('/votes', async (req, res) => { const supabase = getSupabaseClient(); const { initiative_id, user_id, vote_type } = req.body; - // upsert: если голос уже есть, обновить, иначе создать - const { data, error } = await supabase.from('votes').upsert([ - { initiative_id, user_id, vote_type } - ], { onConflict: ['initiative_id', 'user_id'] }).select().single(); - if (error) return res.status(400).json({ error: error.message }); - res.json(data); + + // Проверяем существующий голос + const { data: existingVote, error: checkError } = await supabase + .from('votes') + .select('*') + .eq('initiative_id', initiative_id) + .eq('user_id', user_id) + .single(); + + if (checkError && checkError.code !== 'PGRST116') { + console.log('1/votes') + return res.status(400).json({ error: checkError.message }); + } + + if (existingVote) { + if (existingVote.vote_type === vote_type) { + // Если нажали тот же тип голоса - УДАЛЯЕМ (отменяем голос) + const { error: deleteError } = await supabase + .from('votes') + .delete() + .eq('initiative_id', initiative_id) + .eq('user_id', user_id); + + if (deleteError) return res.status(400).json({ error: deleteError.message }); + res.json({ message: 'Vote removed', action: 'removed', previous_vote: existingVote.vote_type }); + } else { + // Если нажали другой тип голоса - ОБНОВЛЯЕМ + const { data, error } = await supabase + .from('votes') + .update({ vote_type }) + .eq('initiative_id', initiative_id) + .eq('user_id', user_id) + .select() + .single(); + + if (error) return res.status(400).json({ error: error.message }); + res.json({ ...data, action: 'updated', previous_vote: existingVote.vote_type }); + } + } else { + // Если голоса нет - СОЗДАЕМ новый + const { data, error } = await supabase + .from('votes') + .insert([{ initiative_id, user_id, vote_type }]) + .select() + .single(); + + if (error) return res.status(400).json({ error: error.message }); + res.json({ ...data, action: 'created' }); + } }); module.exports = router; \ No newline at end of file