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. +
+
` : ''}
- ${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); }