Skip to content

Commit 6fe1d0e

Browse files
foenx0315RizonFTWCodeMeAPixel
authored
Ranranaway (#8)
* feat(add): introduce new components, hooks, and API routes; update existing files and configurations * shift every single thing to react-icons and more bug fixes * shift every single thing to react-icons and more bug fixes * shift every single thing to react-icons and more bug fixes * everything works! * chore: update change logs * fix: dashboard navbar text color and hover * feat: update database from PostgreSQL to MySQL (wordings not like db db), add system status API, and enhance footer with status display * feat(add): new nsfw warning * refactor: improve user authentication logic and enhance API response handling * chore: update changelog * feat: implement NSFW warning modal with age verification for links containing adult content * chore: update og logic * chore: update og logic * Update README.md * Update README.md * Update CHANGELOG.md for version 0.3.2, including new features, improvements, and bug fixes. Upgrade Next.js and React versions in package.json. Enhance account linking logic in account-linking.tsx and improve QR code download functionality in share-modal.tsx. Fix location flag URL in location-stats.tsx. * Update CHANGELOG.md for version 0.3.2, including new features, improvements, and bug fixes. Upgrade Next.js and React versions in package.json. Enhance account linking logic in account-linking.tsx and improve QR code download functionality in share-modal.tsx. Fix location flag URL in location-stats.tsx. --------- Co-authored-by: RizonFTW <rizon@nodebyte.co.uk> Co-authored-by: Rizon <kye021@hotmail.co.uk> Co-authored-by: Pixelated <toxic.dev09@gmail.com>
1 parent 6cf858e commit 6fe1d0e

File tree

6 files changed

+204
-117
lines changed

6 files changed

+204
-117
lines changed

CHANGELOG.md

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- Bulk link import/export
1717
- Link scheduling
1818

19-
## [0.3.1] - 2025-09-23
20-
### 🚀 New Features
21-
- 🌐 **Social Meta Customization** — users can now fully customize how their Lynkr profile looks when shared on social media (custom backgrounds, layouts, typography, and live preview).
22-
- ⚠️ **NSFW Warning Modal** — added age verification prompt for links marked as sensitive.
23-
24-
### ⚡ Improvements
25-
- 🔄 Migrated database from **PostgreSQL → MySQL** for better performance and consistency.
26-
- 🎨 Unified all icons under **react-icons** for improved consistency across the app.
27-
- 🔐 Refactored user authentication logic with enhanced API responses for smoother login and onboarding.
28-
- 🛠️ Improved Open Graph (OG) logic for better link previews.
29-
- 🖼️ Added real-time theme application for meta images when sharing links.
30-
31-
### 🐛 Bug Fixes
32-
- 🎯 Fixed dashboard navbar text color and hover states.
33-
- ⚙️ Resolved minor layout, icon, and preview inconsistencies.
19+
## [0.3.2] - 2025-09-29
20+
21+
### ⚡ Improvements
22+
23+
- 🔄 Updated site to NextJs V15
24+
25+
### 🐛 Bug Fixes
26+
27+
- 🎯 Fixed QR code not downloading issue
28+
29+
## [0.3.1] - 2025-09-23
30+
31+
### 🚀 New Features
32+
33+
- 🌐 **Social Meta Customization** — users can now fully customize how their Lynkr profile looks when shared on social media (custom backgrounds, layouts, typography, and live preview).
34+
- ⚠️ **NSFW Warning Modal** — added age verification prompt for links marked as sensitive.
35+
36+
### ⚡ Improvements
37+
38+
- 🔄 Migrated database from **PostgreSQL → MySQL** for better performance and consistency.
39+
- 🎨 Unified all icons under **react-icons** for improved consistency across the app.
40+
- 🔐 Refactored user authentication logic with enhanced API responses for smoother login and onboarding.
41+
- 🛠️ Improved Open Graph (OG) logic for better link previews.
42+
- 🖼️ Added real-time theme application for meta images when sharing links.
43+
44+
### 🐛 Bug Fixes
45+
46+
- 🎯 Fixed dashboard navbar text color and hover states.
47+
- ⚙️ Resolved minor layout, icon, and preview inconsistencies.
3448

3549
## [0.3.0] - 2025-08-08
3650

README.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
[![GitHub License](https://img.shields.io/github/license/LynkrApp/Website?style=for-the-badge)](https://github.com/LynkrApp/Website/blob/main/LICENSE)
1313
[![Discord](https://img.shields.io/discord/1387524650895933540?style=for-the-badge&logo=discord)](https://discord.gg/g76w2v7RzG)
1414

15-
[🌐 Live Demo](https://lynkr.link)[📖 Documentation](#getting-started)[🐛 Report Bug](https://github.com/LynkrApp/Website/issues)[💡 Request Feature](https://github.com/LynkrApp/Website/issues)
15+
[🌐 Live Demo](https://lynkr.link)[📖 Documentation](#getting-started)[🐛 Report Bug](https://github.com/LynkrApp/Website/issues)[💡 Request Feature](https://github.com/LynkrApp/Website/issues)
16+
1617
</div>
1718

1819
---
@@ -46,19 +47,21 @@
4647

4748
### Prerequisites
4849

49-
- Node.js 18+
50+
- Node.js 18+
5051
- npm or yarn or bun
5152
- MySQL database
5253

5354
### Installation
5455

5556
1. **Clone the repository**
57+
5658
```bash
5759
git clone https://github.com/LynkrApp/Website.git
5860
cd Website
5961
```
6062

6163
2. **Install dependencies**
64+
6265
```bash
6366
npm install
6467
# or
@@ -68,37 +71,42 @@
6871
```
6972

7073
3. **Set up environment variables**
74+
7175
```bash
7276
cp .env.example .env.local
7377
```
74-
78+
7579
Fill in your environment variables:
80+
7681
```env
7782
# Database
7883
DATABASE_URL="mysql://USER:PASSWORD@HOST:PORT/DATABASEr"
79-
84+
85+
8086
# NextAuth
8187
NEXTAUTH_URL="http://localhost:3000"
8288
NEXTAUTH_SECRET="your-secret-key"
83-
89+
8490
# OAuth Providers
8591
GOOGLE_CLIENT_ID="your-google-client-id"
8692
GOOGLE_CLIENT_SECRET="your-google-client-secret"
87-
93+
8894
GITHUB_CLIENT_ID="your-github-client-id"
8995
GITHUB_CLIENT_SECRET="your-github-client-secret"
90-
96+
9197
DISCORD_CLIENT_ID="your-discord-client-id"
9298
DISCORD_CLIENT_SECRET="your-discord-client-secret"
9399
```
94100

95101
4. **Set up the database**
102+
96103
```bash
97104
npx prisma migrate dev
98105
npx prisma generate
99106
```
100107

101108
5. **Run the development server**
109+
102110
```bash
103111
npm run dev
104112
# or

components/core/account-linking/account-linking.tsx

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@ import { FaDiscord, FaGithub, FaGoogle } from 'react-icons/fa';
88
import React from 'react';
99
import ReAuthModal from '@/components/shared/modals/reauth-modal';
1010
import { CheckCircle, X, Link as LinkIcon } from 'lucide-react';
11-
import type { IconType } from 'react-icons';
1211

1312
const AccountLinking = () => {
1413
const { data: session } = useSession();
1514
const queryClient = useQueryClient();
16-
const [loadingProvider, setLoadingProvider] = useState(null);
15+
const [loadingProvider, setLoadingProvider] = useState<string | null>(null);
1716
const [showReAuthModal, setShowReAuthModal] = useState(false);
18-
const [providerToLink, setProviderToLink] = useState(null);
17+
const [providerToLink, setProviderToLink] = useState<string | null>(null);
1918

2019
// Fetch linked accounts
2120
const {
@@ -32,41 +31,55 @@ const AccountLinking = () => {
3231
});
3332

3433
// Handle re-authentication completion
35-
const handleReAuthCompletion = useCallback(async (token, linkProvider) => {
36-
try {
37-
console.log(
38-
'Re-auth completed, will start linking in 2 seconds...',
39-
linkProvider
40-
);
41-
setLoadingProvider(linkProvider);
34+
const handleReAuthCompletion = useCallback(
35+
async (token: string, linkProvider: string) => {
36+
try {
37+
console.log(
38+
'Re-auth completed, will start linking in 2 seconds...',
39+
linkProvider
40+
);
41+
setLoadingProvider(linkProvider);
4242

43-
// Add a delay to ensure the previous OAuth flow has fully completed
44-
// This prevents OAuth state conflicts between GitHub reauth and Discord linking
45-
setTimeout(() => {
46-
console.log('Starting Discord OAuth flow for account linking');
47-
signIn(linkProvider, {
48-
callbackUrl: `/admin/settings?tab=accounts&action=complete&token=${token}`,
49-
});
50-
}, 2000); // 2 second delay to ensure OAuth state is cleared
51-
} catch (error) {
52-
console.error('Error completing re-auth:', error);
53-
toast.error('Failed to complete account linking');
54-
setLoadingProvider(null);
55-
}
56-
}, []);
43+
// Add a delay to prevent OAuth state conflicts
44+
setTimeout(() => {
45+
console.log(
46+
'Starting OAuth flow for account linking with:',
47+
linkProvider
48+
);
49+
signIn(linkProvider, {
50+
callbackUrl: `/admin/settings?tab=accounts&action=complete&token=${token}&linkProvider=${linkProvider}`,
51+
});
52+
}, 2000);
53+
} catch (error) {
54+
console.error('Error completing re-auth:', error);
55+
toast.error('Failed to complete account linking');
56+
setLoadingProvider(null);
57+
}
58+
},
59+
[]
60+
);
5761

5862
// Handle account linking completion
5963
const handleLinkCompletion = useCallback(
60-
async (token) => {
64+
async (token: string, linkProvider: string | null) => {
6165
try {
62-
console.log('Processing account link completion with token:', token);
66+
console.log(
67+
'Processing account link completion with token:',
68+
token,
69+
'provider:',
70+
linkProvider
71+
);
6372

64-
const response = await axios.post('/api/auth/process-link', { token });
73+
const response = await axios.post('/api/auth/process-link', {
74+
token,
75+
linkProvider,
76+
});
6577

6678
if (response.status === 200) {
6779
toast.success('Account linked successfully!');
68-
refetch(); // Refresh the linked accounts list
80+
refetch();
6981
setLoadingProvider(null);
82+
setProviderToLink(null);
7083
}
7184
} catch (error) {
7285
console.error('Error completing account link:', error);
@@ -75,6 +88,7 @@ const AccountLinking = () => {
7588
: undefined;
7689
toast.error(message || 'Failed to link account');
7790
setLoadingProvider(null);
91+
setProviderToLink(null);
7892
}
7993
},
8094
[refetch]
@@ -94,37 +108,23 @@ const AccountLinking = () => {
94108
});
95109

96110
if (action === 'link') {
97-
// Refresh the linked accounts data after regular sign-in
98111
refetch();
99112
setLoadingProvider(null);
100-
// Clear URL to prevent re-triggering
101113
window.history.replaceState({}, '', '/admin/settings?tab=accounts');
102114
} else if (action === 'reauth' && token && linkProvider) {
103-
// Handle re-authentication completion
104-
console.log(
105-
'Re-authentication completed, preparing to link:',
106-
linkProvider
107-
);
108-
109-
// Clear the URL parameters first to prevent re-triggering
110-
const newUrl = window.location.pathname + '?tab=accounts';
111-
window.history.replaceState({}, '', newUrl);
112-
113-
// Add a delay and then trigger the Discord linking
115+
// Clear URL first to prevent re-triggering
116+
window.history.replaceState({}, '', '/admin/settings?tab=accounts');
114117
handleReAuthCompletion(token, linkProvider);
115118
} else if (action === 'complete' && token) {
116-
// Handle account linking completion
117-
console.log('CALLING handleLinkCompletion with token:', token);
118-
handleLinkCompletion(token);
119-
120119
// Clear URL immediately to prevent duplicate calls
121120
window.history.replaceState({}, '', '/admin/settings?tab=accounts');
121+
handleLinkCompletion(token, linkProvider);
122122
}
123123
}, [refetch, handleLinkCompletion, handleReAuthCompletion]);
124124

125125
// Unlink account mutation
126126
const unlinkMutation = useMutation({
127-
mutationFn: async (provider) => {
127+
mutationFn: async (provider: string) => {
128128
await axios.delete(`/api/auth/unlink-account?provider=${provider}`);
129129
},
130130
onSuccess: () => {
@@ -160,31 +160,35 @@ const AccountLinking = () => {
160160
},
161161
] as const;
162162

163-
const handleLinkAccount = (providerId) => {
163+
const handleLinkAccount = (providerId: string) => {
164164
setProviderToLink(providerId);
165165
setShowReAuthModal(true);
166166
};
167167

168168
const handleReAuthSuccess = () => {
169169
setShowReAuthModal(false);
170-
setLoadingProvider(providerToLink);
170+
if (providerToLink) {
171+
setLoadingProvider(providerToLink);
172+
}
171173
};
172174

173175
const handleCloseReAuthModal = () => {
174176
setShowReAuthModal(false);
175177
setProviderToLink(null);
176178
};
177179

178-
const handleUnlinkAccount = (provider) => {
180+
const handleUnlinkAccount = (provider: string) => {
179181
if (linkedAccounts?.length <= 1) {
180182
toast.error('You must have at least one linked account');
181183
return;
182184
}
183185
unlinkMutation.mutate(provider);
184186
};
185187

186-
const isLinked = (providerId) => {
187-
return linkedAccounts?.some((account) => account.provider === providerId);
188+
const isLinked = (providerId: string) => {
189+
return linkedAccounts?.some(
190+
(account: any) => account.provider === providerId
191+
);
188192
};
189193

190194
if (isLoading) {
@@ -212,9 +216,7 @@ const AccountLinking = () => {
212216
<div className="space-y-4">
213217
{providers.map((provider) => {
214218
const linked = isLinked(provider.id);
215-
const IconComponent = provider.icon as React.ComponentType<
216-
React.SVGProps<SVGSVGElement>
217-
>;
219+
const IconComponent = provider.icon;
218220

219221
return (
220222
<div

components/core/profile-analytics/location-stats.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export const LocationStats = ({
4646
{location ? (
4747
<div className="h-8 w-8 border rounded-full">
4848
<img
49-
src={`https://flag.vercel.app/m/${location}.svg`}
49+
src={`https://flag.vercel.app/l/${location}.svg`}
5050
alt={location}
5151
className="h-8 w-8 blur-0 rounded-full lg:h-8 lg:w-8"
5252
loading="lazy"

0 commit comments

Comments
 (0)