-
-
Notifications
You must be signed in to change notification settings - Fork 41
Analytics Integration & Modal Optimization #112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Summary of ChangesHello @sunithvs, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly upgrades the application's analytics infrastructure by migrating from NocoDB to Supabase, ensuring more robust and non-blocking data collection. Concurrently, it refines the user experience through intelligent modal display logic with a 24-hour cooldown and boosts navigation speed within the GitHub modal, all while maintaining comprehensive tracking of user interactions and referral sources. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request does a great job of migrating the analytics from NocoDB to Supabase and optimizing the user experience with faster navigation and smarter modal display logic. The code is well-structured, and the use of a fire-and-forget approach for analytics calls is a good performance choice.
I've left a few suggestions to improve code maintainability by reducing duplication and making some logic more concise. Specifically, I've pointed out opportunities to refactor duplicated functions and repetitive code blocks. These changes should make the codebase even cleaner and easier to manage in the future. Overall, this is a solid set of improvements.
| const urlSearchParams = new URLSearchParams(); | ||
| if (searchParams) { | ||
| Object.entries(searchParams).forEach(([key, value]) => { | ||
| if (value && typeof value === 'string') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value && check filters out empty strings (e.g., from ?ref=), which might be unintentional as empty strings can be valid parameter values. The typeof value === 'string' check already handles null and undefined. Consider removing value && to allow tracking of parameters with empty values.
| if (value && typeof value === 'string') { | |
| if (typeof value === 'string') { |
| setLoading(true); | ||
| await router.push(`/${profile?.login}?ref=modal`); | ||
|
|
||
| // Get current search params and preserve them | ||
| const currentParams = new URLSearchParams(window.location.search); | ||
| currentParams.set('ref', 'modal'); | ||
|
|
||
| // Use window.location for instant navigation | ||
| window.location.href = `/${profile?.login}?${currentParams.toString()}`; | ||
| }; | ||
|
|
||
| // no need to setLoading(false) because navigation will replace this page | ||
| const redirectToProfilePageFromCard = () => { | ||
| if (!profile) return; | ||
|
|
||
| // Get current search params and preserve them | ||
| const currentParams = new URLSearchParams(window.location.search); | ||
| currentParams.set('ref', 'modelv2'); | ||
|
|
||
| // Use window.location for instant navigation | ||
| window.location.href = `/${profile?.login}?${currentParams.toString()}`; | ||
| }; | ||
| // Debounce the username input to prevent excessive API calls | ||
| const debouncedUsername = useDebounce(username, 500); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's code duplication between redirectToProfilePage and redirectToProfilePageFromCard. You can extract the common navigation logic into a helper function to improve maintainability and reduce redundancy.
const navigateToProfile = (ref: 'modal' | 'modelv2') => {
if (!profile) return;
// Get current search params and preserve them
const currentParams = new URLSearchParams(window.location.search);
currentParams.set('ref', ref);
// Use window.location for instant navigation
window.location.href = `/${profile.login}?${currentParams.toString()}`;
};
const redirectToProfilePage = () => {
setLoading(true);
navigateToProfile('modal');
};
const redirectToProfilePageFromCard = () => {
navigateToProfile('modelv2');
};
| // Utility function to detect provider from URL | ||
| const detectProvider = (url: string): string => { | ||
| const urlLower = url.toLowerCase(); | ||
| if (urlLower.includes('medium.com')) return 'medium'; | ||
| if (urlLower.includes('instagram.com')) return 'instagram'; | ||
| if (urlLower.includes('huggingface.co')) return 'huggingface'; | ||
| return 'generic'; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This detectProvider function is duplicated in www/components/ProfileSection.tsx. To avoid code duplication, it should be centralized in a shared location and imported where needed.
While you're at it, you could improve this function by adding detection for devb.io URLs. This would allow you to simplify the switch statement in addUserToSupabase by creating a separate case "devb": instead of nesting the logic inside the generic case.
Example update for detectProvider:
if (urlLower.includes('devb.io')) return 'devb';| // UTM parameters | ||
| const utmSource = searchParams.get('utm_source'); | ||
| const utmMedium = searchParams.get('utm_medium'); | ||
| const utmCampaign = searchParams.get('utm_campaign'); | ||
| const utmTerm = searchParams.get('utm_term'); | ||
| const utmContent = searchParams.get('utm_content'); | ||
|
|
||
| // Referral parameter | ||
| const ref = searchParams.get('ref'); | ||
|
|
||
| // Add to mapped data if they exist | ||
| if (utmSource) mappedData['utm_source'] = utmSource; | ||
| if (utmMedium) mappedData['utm_medium'] = utmMedium; | ||
| if (utmCampaign) mappedData['utm_campaign'] = utmCampaign; | ||
| if (utmTerm) mappedData['utm_term'] = utmTerm; | ||
| if (utmContent) mappedData['utm_content'] = utmContent; | ||
| if (ref) mappedData['ref'] = ref; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block of code for handling UTM parameters and ref is repetitive. You can use a loop to make it more concise and easier to maintain if more parameters are added in the future.
| // UTM parameters | |
| const utmSource = searchParams.get('utm_source'); | |
| const utmMedium = searchParams.get('utm_medium'); | |
| const utmCampaign = searchParams.get('utm_campaign'); | |
| const utmTerm = searchParams.get('utm_term'); | |
| const utmContent = searchParams.get('utm_content'); | |
| // Referral parameter | |
| const ref = searchParams.get('ref'); | |
| // Add to mapped data if they exist | |
| if (utmSource) mappedData['utm_source'] = utmSource; | |
| if (utmMedium) mappedData['utm_medium'] = utmMedium; | |
| if (utmCampaign) mappedData['utm_campaign'] = utmCampaign; | |
| if (utmTerm) mappedData['utm_term'] = utmTerm; | |
| if (utmContent) mappedData['utm_content'] = utmContent; | |
| if (ref) mappedData['ref'] = ref; | |
| const paramsToTrack = [ | |
| 'utm_source', | |
| 'utm_medium', | |
| 'utm_campaign', | |
| 'utm_term', | |
| 'utm_content', | |
| 'ref', | |
| ]; | |
| paramsToTrack.forEach((param) => { | |
| const value = searchParams.get(param); | |
| if (value) { | |
| mappedData[param] = value; | |
| } | |
| }); |
📋 Overview
This PR implements a comprehensive analytics integration with Supabase, replaces NocoDB with a more robust tracking system, adds localStorage-based modal expiry, and optimizes navigation performance in the GitHub modal.
🎯 Key Features
1. Supabase Analytics Integration
2. SupportModal Improvements
3. GitHub Modal Navigation Optimization
window.location.href🔧 Technical Changes
Modified Files
Core Analytics (
www/lib/api.ts)addUserToNocodb()→addUserToSupabase()utm_source,utm_medium,utm_campaign,utm_term,utm_content)refparameter)Record<string, string>)Profile Section (
www/components/ProfileSection.tsx)Page Component (
www/app/[username]/page.tsx)Support Modal (
www/components/modal/support-modal.tsx)GitHub Modal (
www/components/github-modal/client.tsx)window.location.hrefref=modelv2Environment Configuration (
www/example.env)📊 Data Mapping
Analytics Data Structure
Social Media Detection
linkedin.comURLs →"Linkedin"fieldtwitter.comURLs →"twitter"fieldmedium.comURLs →"Medium"fieldinstagram.comURLs →"instagram"fielddevb.ioURLs →"devb"field"generic 1","generic 2", etc.⚡ Performance Improvements
1. Non-Blocking Analytics
2. Instant Navigation
router.push()with async delayswindow.location.hreffor instant navigation3. Smart Modal Display
🔒 Environment Variables
Required Setup
Supabase Edge Function Whitelist
Update your Supabase function to include:
🧪 Testing
Test Scenarios
ref=modelv2ref=modalManual Testing
🔮 Future Enhancements
✅ Checklist
🎉 Impact
User Experience
Developer Experience