Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/src/app/(auth)/forgot-password/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ForgotPasswordContainer as default } from '@containers';
1 change: 1 addition & 0 deletions frontend/src/app/(auth)/reset-password/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ResetPasswordContainer as default } from '@containers';
93 changes: 58 additions & 35 deletions frontend/src/app/(core)/privacy-policy/page.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,60 @@
"use client";
'use client';

import React from 'react';

import Link from 'next/link';

const PrivacyPolicy = () => {
return (
<div className="container mx-auto px-4 py-12 max-w-4xl">
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-primary mb-4">
Privacy Policy
</h1>
<p className="text-muted-foreground max-w-2xl mx-auto">
<div className='container mx-auto max-w-4xl px-4 py-12'>
<div className='mb-12 text-center'>
<h1 className='mb-4 text-4xl font-bold text-primary'>Privacy Policy</h1>
<p className='mx-auto max-w-2xl text-muted-foreground'>
Last Updated: 2 March, 2025
</p>
</div>

<div className="space-y-8 text-foreground">
<div className='space-y-8 text-foreground'>
<section>
<h2 className="text-2xl font-semibold border-b pb-2 mb-4">
<h2 className='mb-4 border-b pb-2 text-2xl font-semibold'>
1. Introduction
</h2>
<p className="leading-relaxed">
Welcome to Django India! Your privacy is important to us. This Privacy Policy explains how we collect, use, and protect your information when you visit our website (<Link href="https://www.djangoindia.org/home" className="text-primary hover:underline">www.djangoindia.org/home</Link>) and interact with our community.
<p className='leading-relaxed'>
Welcome to Django India! Your privacy is important to us. This
Privacy Policy explains how we collect, use, and protect your
information when you visit our website (
<Link
href='https://www.djangoindia.org/home'
className='text-primary hover:underline'
>
www.djangoindia.org/home
</Link>
) and interact with our community.
</p>
</section>

<section>
<h2 className="text-2xl font-semibold border-b pb-2 mb-4">
<h2 className='mb-4 border-b pb-2 text-2xl font-semibold'>
2. Information We Collect
</h2>
<ul className="list-disc list-inside space-y-2">
<ul className='list-inside list-disc space-y-2'>
<li>
<strong>Personal Information:</strong> When you subscribe to our newsletter, register for events, or contact us, we may collect your name, email address, and any other details you provide.
<strong>Personal Information:</strong> When you subscribe to our
newsletter, register for events, or contact us, we may collect
your name, email address, and any other details you provide.
</li>
<li>
<strong>Cookies:</strong> We use cookies and similar tracking technologies to enhance user experience and improve our website.
<strong>Cookies:</strong> We use cookies and similar tracking
technologies to enhance user experience and improve our website.
</li>
</ul>
</section>

<section>
<h2 className="text-2xl font-semibold border-b pb-2 mb-4">
<h2 className='mb-4 border-b pb-2 text-2xl font-semibold'>
3. How We Use Your Information
</h2>
<ul className="list-disc list-inside space-y-2">
<ul className='list-inside list-disc space-y-2'>
<li>Send updates, newsletters, and event invitations.</li>
<li>Improve our website and community engagement.</li>
<li>Analyze website traffic and trends.</li>
Expand All @@ -52,51 +63,63 @@ const PrivacyPolicy = () => {
</section>

<section>
<h2 className="text-2xl font-semibold border-b pb-2 mb-4">
<h2 className='mb-4 border-b pb-2 text-2xl font-semibold'>
4. Data Sharing and Protection
</h2>
<ul className="list-disc list-inside space-y-2">
<ul className='list-inside list-disc space-y-2'>
<li>We do not sell, trade, or rent your personal information.</li>
<li>We may share data with service providers who help us manage our website and communications.</li>
<li>We take reasonable security measures to protect your data from unauthorized access, disclosure, or loss.</li>
<li>
We may share data with service providers who help us manage our
website and communications.
</li>
<li>
We take reasonable security measures to protect your data from
unauthorized access, disclosure, or loss.
</li>
</ul>
</section>

<section>
<h2 className="text-2xl font-semibold border-b pb-2 mb-4">
<h2 className='mb-4 border-b pb-2 text-2xl font-semibold'>
5. Third-Party Links
</h2>
<p className="leading-relaxed">
Our website may contain links to external sites. We are not responsible for their privacy policies or content.
<p className='leading-relaxed'>
Our website may contain links to external sites. We are not
responsible for their privacy policies or content.
</p>
</section>

<section>
<h2 className="text-2xl font-semibold border-b pb-2 mb-4">
<h2 className='mb-4 border-b pb-2 text-2xl font-semibold'>
6. Your Rights and Choices
</h2>
<ul className="list-disc list-inside space-y-2">
<ul className='list-inside list-disc space-y-2'>
<li>You can unsubscribe from our emails at any time.</li>
<li>You may request access, correction, or deletion of your personal data by contacting us.</li>
<li>
You may request access, correction, or deletion of your personal
data by contacting us.
</li>
</ul>
</section>

<section>
<h2 className="text-2xl font-semibold border-b pb-2 mb-4">
<h2 className='mb-4 border-b pb-2 text-2xl font-semibold'>
7. Changes to This Policy
</h2>
<p className="leading-relaxed">
We may update this Privacy Policy from time to time. Any changes will be posted on this page with an updated effective date.
<p className='leading-relaxed'>
We may update this Privacy Policy from time to time. Any changes
will be posted on this page with an updated effective date.
</p>
</section>

<section>
<h2 className="text-2xl font-semibold border-b pb-2 mb-4">
<h2 className='mb-4 border-b pb-2 text-2xl font-semibold'>
8. Contact Us
</h2>
<p className="leading-relaxed mb-4">
If you have any questions about this Privacy Policy, please contact us at: {" "}
<Link href="mailto:contact@djangoindia.org">
<p className='mb-4 leading-relaxed'>
If you have any questions about this Privacy Policy, please contact
us at:{' '}
<Link href='mailto:contact@djangoindia.org'>
<u>admin@djangoindia.org</u>
</Link>
Comment on lines +120 to 124
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix contact email href mismatch.

The visible email shows admin@djangoindia.org, but the href sends users to mailto:contact@djangoindia.org. That mismatch will route messages to the wrong inbox and confuse users who copy the address. Please align the href with the displayed address (or update the display text) so clicks and copy-paste go to the same destination. (djangoindia.org)

-            <Link href='mailto:contact@djangoindia.org'>
-              <u>admin@djangoindia.org</u>
-            </Link>
+            <Link href='mailto:admin@djangoindia.org'>
+              <u>admin@djangoindia.org</u>
+            </Link>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
If you have any questions about this Privacy Policy, please contact
us at:{' '}
<Link href='mailto:contact@djangoindia.org'>
<u>admin@djangoindia.org</u>
</Link>
If you have any questions about this Privacy Policy, please contact
us at:{' '}
<Link href='mailto:admin@djangoindia.org'>
<u>admin@djangoindia.org</u>
</Link>
🤖 Prompt for AI Agents
frontend/src/app/(core)/privacy-policy/page.tsx around lines 120 to 124: the
mailto href and displayed email are inconsistent (href uses
contact@djangoindia.org while visible text shows admin@djangoindia.org); fix by
making them identical—either change the href to mailto:admin@djangoindia.org to
match the visible text or change the visible text to
admin@contact@djangoindia.org (preferably set both to
mailto:admin@djangoindia.org and display admin@djangoindia.org) so clicks and
copy-paste go to the same address.

</p>
Expand All @@ -106,4 +129,4 @@ const PrivacyPolicy = () => {
);
};

export default PrivacyPolicy;
export default PrivacyPolicy;
42 changes: 22 additions & 20 deletions frontend/src/components/Modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,36 +64,38 @@ const Modal: React.FC<ModalProps> = ({ onClose }) => {
{/* Full Name Field */}
<div className='relative flex flex-col'>
<div className='relative flex items-center'>
<FaRegUser className='absolute left-4 text-gray-500' />
<input
type='text'
placeholder='Full Name'
className={`w-full rounded-full border py-3 pl-10 pr-4 focus:outline-none focus:ring-2 focus:ring-black ${
errors.name ? 'border-red-500' : ''
}`}
{...register('name', { required: true })}
/>
<FaRegUser className='absolute left-4 text-gray-500' />
<input
type='text'
placeholder='Full Name'
className={`w-full rounded-full border py-3 pl-10 pr-4 focus:outline-none focus:ring-2 focus:ring-black ${
errors.name ? 'border-red-500' : ''
}`}
{...register('name', { required: true })}
/>
</div>
{errors.name && (
<p className='text-sm text-red-500 mt-1'>{errors.name.message}</p>
<p className='mt-1 text-sm text-red-500'>{errors.name.message}</p>
)}
</div>

{/* Email Field */}
<div className='relative flex flex-col'>
<div className='relative flex items-center'>
<MdOutlineEmail className='absolute left-4 text-gray-500' />
<input
type='email'
placeholder='Email'
className={`w-full rounded-full border py-3 pl-10 pr-4 focus:outline-none focus:ring-2 focus:ring-black ${
errors.email ? 'border-red-500' : ''
}`}
{...register('email', { required: true })}
/>
<MdOutlineEmail className='absolute left-4 text-gray-500' />
<input
type='email'
placeholder='Email'
className={`w-full rounded-full border py-3 pl-10 pr-4 focus:outline-none focus:ring-2 focus:ring-black ${
errors.email ? 'border-red-500' : ''
}`}
{...register('email', { required: true })}
/>
</div>
{errors.email && (
<p className='text-sm text-red-500 mt-1'>{errors.email.message}</p>
<p className='mt-1 text-sm text-red-500'>
{errors.email.message}
</p>
)}
</div>

Expand Down
1 change: 1 addition & 0 deletions frontend/src/constants/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export const API_ENDPOINTS = {
requestVerification: '/request-email-verify',
profile: '/users/me',
changePassword: '/users/me/set-password',
forgotPassword: '/forgot-password',
};
82 changes: 57 additions & 25 deletions frontend/src/constants/schema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,46 +141,78 @@ export const SIGNUP_FORM_SCHEMA = yup.object({
/[@$!%*?&#]/,
'Password must contain at least one special character (@, $, !, %, *, ?, &, or #).',
),
confirmPassword: yup
.string()
.when('newPassword', {
is: (newPassword: string) => newPassword && newPassword.length > 0,
then: (schema) => schema
confirmPassword: yup.string().when('newPassword', {
is: (newPassword: string) => newPassword && newPassword.length > 0,
then: (schema) =>
schema
.required('Confirm Password is required')
.oneOf([yup.ref('newPassword')], 'Passwords must match'),
otherwise: (schema) => schema.optional().nullable()
}),
otherwise: (schema) => schema.optional().nullable(),
}),
Comment on lines +144 to +151
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Resolve Biome noThenProperty lint errors in yup .when usage

Biome fails the build here because the object literal handed to .when exposes a callable then property, which the lint/suspicious/noThenProperty rule flags as a potential thenable. Switch to the callback overload so we keep the same validation while satisfying the linter.

-  confirmPassword: yup.string().when('newPassword', {
-    is: (newPassword: string) => newPassword && newPassword.length > 0,
-    then: (schema) =>
-      schema
-        .required('Confirm Password is required')
-        .oneOf([yup.ref('newPassword')], 'Passwords must match'),
-    otherwise: (schema) => schema.optional().nullable(),
-  }),
+  confirmPassword: yup
+    .string()
+    .when('newPassword', (newPassword, schema) =>
+      newPassword && newPassword.length > 0
+        ? schema
+            .required('Confirm Password is required')
+            .oneOf([yup.ref('newPassword')], 'Passwords must match')
+        : schema.optional().nullable(),
+    ),
-  confirmPassword: yup.string().when('newPassword', {
-    is: (newPassword: string) => newPassword && newPassword.length > 0,
-    then: (schema) =>
-      schema
-        .required('Confirm Password is required')
-        .oneOf([yup.ref('newPassword')], 'Passwords must match'),
-    otherwise: (schema) => schema.optional().nullable(),
-  }),
+  confirmPassword: yup
+    .string()
+    .when('newPassword', (newPassword, schema) =>
+      newPassword && newPassword.length > 0
+        ? schema
+            .required('Confirm Password is required')
+            .oneOf([yup.ref('newPassword')], 'Passwords must match')
+        : schema.optional().nullable(),
+    ),

As reported by Biome.

Also applies to: 210-217

🧰 Tools
🪛 Biome (2.1.2)

[error] 146-146: Do not add then to an object.

(lint/suspicious/noThenProperty)

🤖 Prompt for AI Agents
frontend/src/constants/schema.tsx around lines 144-151 (and similarly update
lines 210-217): the yup .when currently uses an object with a then property
which triggers Biome's noThenProperty lint rule; replace the object overload
with the callback overload signature: call .when('newPassword',
(newPasswordValue, schema) => { return newPasswordValue &&
newPasswordValue.length > 0 ? schema.required('Confirm Password is
required').oneOf([yup.ref('newPassword')], 'Passwords must match') :
schema.optional().nullable(); }); apply the same pattern to the other occurrence
on lines 210-217 to remove the callable then property and satisfy the linter.

});

export const FORGOT_PASSWORD_SCHEMA = yup.object({
email: yup
.string()
.email('Please enter a valid email address')
.required('Email is required'),
});

export const RESET_PASSWORD_SCHEMA = yup.object({
new_password: yup
.string()
.required('Password is required.')
.min(8, 'Password must be at least 8 characters long.')
.max(20, 'Password cannot exceed 20 characters.')
.matches(/[A-Z]/, 'Password must contain at least one uppercase letter.')
.matches(/[a-z]/, 'Password must contain at least one lowercase letter.')
.matches(/[0-9]/, 'Password must contain at least one number.')
.matches(
/[@$!%*?&#]/,
'Password must contain at least one special character (@, $, !, %, *, ?, &, or #).',
),
confirm_password: yup
.string()
.required('Confirm password is required') // Ensure this is required
.oneOf([yup.ref('new_password')], 'Passwords must match'),
});

export const EDIT_PROFILE_FORM_SCHEMA = yup.object({
username: yup.string().required("Username is required"),
email: yup.string().email("Invalid email").required("Email is required").meta({ disabled: true }),
first_name: yup.string().required("First Name is required"),
last_name: yup.string().required("Last Name is required"),
username: yup.string().required('Username is required'),
email: yup
.string()
.email('Invalid email')
.required('Email is required')
.meta({ disabled: true }),
first_name: yup.string().required('First Name is required'),
last_name: yup.string().required('Last Name is required'),
gender: yup.string().optional().nullable(),
bio: yup.string().optional().nullable(),
about: yup.string().optional().nullable(),

website: yup.string().url("Invalid URL").optional().nullable(),
linkedin: yup.string().url("Invalid URL").optional().nullable(),
instagram: yup.string().url("Invalid URL").optional().nullable(),
github: yup.string().url("Invalid URL").optional().nullable(),
twitter: yup.string().url("Invalid URL").optional().nullable(),
mastodon: yup.string().url("Invalid URL").optional().nullable(),
website: yup.string().url('Invalid URL').optional().nullable(),
linkedin: yup.string().url('Invalid URL').optional().nullable(),
instagram: yup.string().url('Invalid URL').optional().nullable(),
github: yup.string().url('Invalid URL').optional().nullable(),
twitter: yup.string().url('Invalid URL').optional().nullable(),
mastodon: yup.string().url('Invalid URL').optional().nullable(),

country: yup.string().optional().nullable(),
organization: yup.string().optional().nullable(),
user_timezone: yup.string().optional().nullable(),
});

export const CHANGE_PASSWORD_FORM_SCHEMA = yup.object({
newPassword: yup.string().min(6, "Password must be at least 6 characters").required("Password is required"),
confirmPassword: yup.string()
.when('newPassword', {
is: (newPassword: string) => newPassword && newPassword.length > 0,
then: (schema) => schema
newPassword: yup
.string()
.min(6, 'Password must be at least 6 characters')
.required('Password is required'),
confirmPassword: yup.string().when('newPassword', {
is: (newPassword: string) => newPassword && newPassword.length > 0,
then: (schema) =>
schema
.required('Confirm Password is required')
.oneOf([yup.ref('newPassword')], 'Passwords must match'),
otherwise: (schema) => schema.optional().nullable()
}),
});
otherwise: (schema) => schema.optional().nullable(),
}),
});
Loading