diff --git a/src/index.js b/src/index.js index 5ab704a..3ae5b71 100644 --- a/src/index.js +++ b/src/index.js @@ -61,6 +61,13 @@ app.post('/register', async c => { 'INSERT INTO users (email, password_hash, full_name, phone) VALUES (?, ?, ?, ?)' ).bind(email, hash, fullName, phone).run(); + // Notify team of new registration โ high-intent signal + c.executionCtx.waitUntil(pushLeadToKondesk(c.env, { + fullName, email, phone, + service: '๐ New Account Registration', + message: `New user registered on the portal. Name: ${fullName}, Phone: ${phone}`, + })); + const { token, expires } = await createSession(c.env, result.meta.last_row_id); c.header('Set-Cookie', `session=${token}; Path=/; HttpOnly; SameSite=Lax; Expires=${expires.toUTCString()}`); return c.redirect('/dashboard'); @@ -116,7 +123,7 @@ app.get('/courses', async c => { error = r.error || null; } - return c.html(coursesPage(c.get('user'), results, params, fromCache, error)); + return c.html(coursesPage(c.get('user'), results, params, fromCache, error, c.req.query('saved')||'')); }); // โโ DASHBOARD โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ @@ -124,7 +131,7 @@ app.get('/dashboard', async c => { const user = c.get('user'); if (!user) return c.redirect('/login?redirect=/dashboard'); const [inquiriesRes, profileRes, docsRes, timelineRes] = await Promise.all([ - c.env.DB.prepare('SELECT * FROM inquiries WHERE user_id=? ORDER BY created_at DESC LIMIT 10').bind(user.id).all(), + c.env.DB.prepare('SELECT * FROM inquiries WHERE user_id=? ORDER BY created_at DESC LIMIT 30').bind(user.id).all(), c.env.DB.prepare('SELECT * FROM visa_profiles WHERE user_id=?').bind(user.id).first(), c.env.DB.prepare('SELECT * FROM document_expiries WHERE user_id=? ORDER BY expiry_date ASC LIMIT 5').bind(user.id).all(), c.env.DB.prepare('SELECT * FROM case_timelines WHERE user_id=?').bind(user.id).all(), @@ -150,11 +157,37 @@ app.get('/dashboard', async c => { app.get('/dashboard/save', async c => { const user = c.get('user'); if (!user) return c.redirect('/login?redirect=/courses'); - const { code, name, provider } = { code: c.req.query('code'), name: c.req.query('name'), provider: c.req.query('provider') }; - await c.env.DB.prepare( - 'INSERT INTO inquiries (user_id, full_name, email, service, cricos_course_code, cricos_course_name, cricos_provider) VALUES (?, ?, ?, ?, ?, ?, ?)' - ).bind(user.id, user.full_name, user.email, 'Saved Course', code||'', name||'', provider||'').run(); - return c.redirect('/dashboard'); + const code = c.req.query('code') || ''; + const name = c.req.query('name') || ''; + const provider = c.req.query('provider') || ''; + const back = c.req.query('back') || ''; // search URL to return to + + // Check if already saved + const existing = await c.env.DB.prepare( + 'SELECT id FROM inquiries WHERE user_id=? AND cricos_course_code=? AND service=?' + ).bind(user.id, code, 'Saved Course').first(); + + if (!existing) { + await c.env.DB.prepare( + 'INSERT INTO inquiries (user_id, full_name, email, service, cricos_course_code, cricos_course_name, cricos_provider) VALUES (?, ?, ?, ?, ?, ?, ?)' + ).bind(user.id, user.full_name, user.email, 'Saved Course', code, name, provider).run(); + + // Notify team โ course save is high-intent + c.executionCtx.waitUntil(pushLeadToKondesk(c.env, { + fullName: user.full_name, + email: user.email, + phone: user.phone || '', + service: '๐พ Course Saved', + cricosCode: code, + courseName: name, + provider, + message: `${user.full_name} saved a course to their dashboard: ${name} (${code}) at ${provider}`, + })); + } + + // Return to courses page with saved=1 flag so we can show a confirmation + const returnUrl = back ? `${back}&saved=${encodeURIComponent(code)}` : `/courses?saved=${encodeURIComponent(code)}`; + return c.redirect(returnUrl); }); // โโ VISA TRACKER: POINTS CALCULATOR โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ diff --git a/src/templates.js b/src/templates.js index feccf4f..abedd05 100644 --- a/src/templates.js +++ b/src/templates.js @@ -489,11 +489,14 @@ function homePage(user) { `, user, '', { url: '/', description: 'Careers Gateway Australia โ your trusted partner for education, migration, recruitment, RPL, and visa services. Search 26,000+ CRICOS courses and book a free consultation.', image: 'https://careersgateway.com.au/wp-content/uploads/2025/06/pexels-photo-1236421-1236421-scaled.jpg' }); } -function coursesPage(user, results, params, fromCache, error) { +function coursesPage(user, results, params, fromCache, error, savedCode = '') { const hasSearch = Object.values(params).some(v => v); const stateOptions = ['NSW','VIC','QLD','WA','SA','TAS','ACT','NT']; const levelOptions = [['1','Bachelor Degree'],['2','Master Degree'],['3','Doctoral Degree'],['4','Diploma'],['5','Certificate'],['6','Advanced Diploma'],['7','Graduate Certificate'],['8','Graduate Diploma']]; + // Build the back URL (current search) so save redirects back here + const backUrl = '/courses?' + Object.entries(params).filter(([,v])=>v).map(([k,v])=>`${k}=${encodeURIComponent(v)}`).join('&'); + const courseMeta = { url: '/courses', description: 'Search 26,000+ CRICOS-registered courses from Australian universities and colleges. Filter by state, level, and field of study. Free account required to view results.', image: 'https://careersgateway.com.au/wp-content/uploads/2025/06/pexels-photo-1236421-1236421-scaled.jpg' }; return layout('CRICOS Course Search', ` @@ -504,6 +507,14 @@ function coursesPage(user, results, params, fromCache, error) { + ${savedCode ? ` + + โ + + Course saved to your dashboard! + View all saved courses in your dashboard. + + ` : ''} @@ -606,7 +617,10 @@ function coursesPage(user, results, params, fromCache, error) { Book Consultation - ๐พ Save Course + ${c.cricosCode === savedCode + ? `โ Saved` + : `๐พ Save` + } `).join('')} diff --git a/src/visa-tracker.js b/src/visa-tracker.js index f57220c..efb349d 100644 --- a/src/visa-tracker.js +++ b/src/visa-tracker.js @@ -646,9 +646,9 @@ export function dashboardOverview(user, { inquiries, profile, points, completedS icon: '๐', }, { - label: 'Inquiries', - value: inquiries.length, - sub: 'Total submitted', + label: 'Saved Courses', + value: inquiries.filter(i => i.service === 'Saved Course').length || 'โ', + sub: inquiries.filter(i => i.service !== 'Saved Course').length + ' consultation request' + (inquiries.filter(i => i.service !== 'Saved Course').length !== 1 ? 's' : ''), color: '#1a5bb8', href: '/contact', icon: '๐', @@ -715,18 +715,51 @@ export function dashboardOverview(user, { inquiries, profile, points, completedS - ${inquiries.length > 0 ? ` - - ๐ Recent Inquiries - ${inquiries.slice(0,5).map(i => ` - - - ${esc(i.service||'General Inquiry')}${i.cricos_course_name ? ` โ ${esc(i.cricos_course_name)}` : ''} - ${new Date(i.created_at).toLocaleDateString('en-AU',{day:'numeric',month:'short',year:'numeric'})} - - ${i.kondesk_sent?'โ Processing':'Received'} - `).join('')} - ` : ''}`; + ${(() => { + const savedCourses = inquiries.filter(i => i.service === 'Saved Course'); + const actualInquiries = inquiries.filter(i => i.service !== 'Saved Course'); + return ` + ${savedCourses.length > 0 ? ` + + + ๐พ Saved Courses (${savedCourses.length}) + Search more โ + + ${savedCourses.slice(0,5).map(i => ` + + + ${esc(i.cricos_course_name||'Course')} + ${esc(i.cricos_provider||'')}${i.cricos_course_code ? ` ยท CRICOS: ${esc(i.cricos_course_code)}` : ''} + ${new Date(i.created_at).toLocaleDateString('en-AU',{day:'numeric',month:'short',year:'numeric'})} + + + Book Consultation + + `).join('')} + ` : ''} + + ${actualInquiries.length > 0 ? ` + + ๐ My Inquiries (${actualInquiries.length}) + ${actualInquiries.slice(0,5).map(i => ` + + + ${esc(i.service||'General Inquiry')}${i.cricos_course_name ? ` โ ${esc(i.cricos_course_name)}` : ''} + ${new Date(i.created_at).toLocaleDateString('en-AU',{day:'numeric',month:'short',year:'numeric'})} + + ${i.kondesk_sent?'โ Processing':'Received'} + `).join('')} + ` : ''} + + ${savedCourses.length === 0 && actualInquiries.length === 0 ? ` + + ๐ + You haven't saved any courses yet + Search CRICOS courses and save the ones you're interested in. + Search Courses + ` : ''}`; + })()}`; return dashWrap(user, 'overview', body); }
Search CRICOS courses and save the ones you're interested in.