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
4 changes: 4 additions & 0 deletions src/Routes/Router.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Routes, Route } from "react-router-dom";
import PrivacyPolicy from "../pages/PrivacyPolicy/PrivacyPolicy";
import TermsAndConditions from "../pages/TermsAndConditions/TermsAndConditions";
import Tracker from "../pages/Tracker/Tracker.tsx";
import About from "../pages/About/About";
import Contact from "../pages/Contact/Contact";
Expand All @@ -13,6 +15,8 @@ const Router = () => {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/privacy-policy" element={<PrivacyPolicy />} />
<Route path="/terms-and-conditions" element={<TermsAndConditions />} />
<Route path="/track" element={<Tracker />} />
<Route path="/signup" element={<Signup />} />
<Route path="/login" element={<Login />} />
Expand Down
18 changes: 18 additions & 0 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
FaArrowRight,
FaEnvelope,
FaInfoCircle,
FaShieldAlt,
FaFileContract,
} from 'react-icons/fa';

function Footer() {
Expand Down Expand Up @@ -80,6 +82,22 @@ function Footer() {
<FaInfoCircle className="h-3.5 w-3.5" />
About
</Link>

<Link
to="/privacy-policy"
className="inline-flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
>
<FaShieldAlt className="h-3.5 w-3.5" />
Privacy Policy
</Link>

<Link
to="/terms-and-conditions"
className="inline-flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
>
<FaFileContract className="h-3.5 w-3.5" />
Terms &amp; Conditions
</Link>
</div>
</div>

Expand Down
75 changes: 75 additions & 0 deletions src/components/legal/LegalPageLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { motion } from "framer-motion";

interface Section {
title: string;
content: string;
}

interface LegalPageLayoutProps {
title: string;
intro: string;
sections: Section[];
}

const LegalPageLayout = ({ title, intro, sections }: LegalPageLayoutProps) => {
return (
<div className="bg-gradient-to-br from-white to-gray-100 dark:from-gray-900 dark:to-gray-800 text-black dark:text-white min-h-screen">

{/* Hero */}
<section className="py-24 text-center">
<motion.h1
className="text-5xl font-extrabold mb-4"
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
>
{title}
</motion.h1>
<motion.p
className="text-xl max-w-xl mx-auto text-gray-600 dark:text-gray-300"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.2, duration: 0.6 }}
>
Last updated:{" "}
{new Date().toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
})}
</motion.p>
Comment on lines +34 to +40
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Dynamic date computation is misleading for legal pages.

Computing "Last updated" using new Date() means the date will always show today, not the actual last update date of the legal content. This is misleading for users and potentially problematic for legal compliance, as these dates should reflect when the policy was genuinely last modified.

📅 Proposed fix: Accept lastUpdated as a prop

Update the interface to accept a lastUpdated string:

 interface LegalPageLayoutProps {
   title: string;
   intro: string;
   sections: Section[];
+  lastUpdated: string;
 }

Then use the prop instead of computing the date:

-          Last updated:{" "}
-          {new Date().toLocaleDateString("en-US", {
-            year: "numeric",
-            month: "long",
-            day: "numeric",
-          })}
+          Last updated: {lastUpdated}

Update both page components to pass the actual last updated date:

// In PrivacyPolicy.tsx and TermsAndConditions.tsx
<LegalPageLayout
  title="..."
  intro="..."
  sections={sections}
  lastUpdated="January 1, 2025"
/>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/legal/LegalPageLayout.tsx` around lines 34 - 40, The
LegalPageLayout component currently computes the "Last updated" date with new
Date(), which is misleading; update the LegalPageLayout props/interface to
accept a lastUpdated: string prop, replace the new Date() usage in the render
(the motion.p that prints "Last updated") to display the passed lastUpdated prop
instead, and update the page components that use LegalPageLayout (e.g.,
PrivacyPolicy.tsx and TermsAndConditions.tsx) to pass the canonical last updated
string (e.g., "January 1, 2025") when rendering the layout.

</section>

{/* Content */}
<section className="py-12 px-6 max-w-4xl mx-auto space-y-10 pb-24">
<motion.p
className="text-gray-700 dark:text-gray-300 text-lg leading-relaxed"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.3, duration: 0.6 }}
>
{intro}
</motion.p>

{sections.map((section, idx) => (
<motion.div
key={idx}
className="p-8 bg-white dark:bg-gray-800 shadow-md rounded-2xl border border-gray-100 dark:border-gray-700"
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ delay: idx * 0.1, duration: 0.5 }}
>
<h2 className="text-2xl font-bold mb-3 text-indigo-600 dark:text-indigo-400">
{section.title}
</h2>
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
{section.content}
</p>
</motion.div>
))}
</section>
</div>
);
};

export default LegalPageLayout;
49 changes: 49 additions & 0 deletions src/pages/PrivacyPolicy/PrivacyPolicy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import LegalPageLayout from "../../components/legal/LegalPageLayout";

const sections = [
{
title: "Information We Collect",
content:
"We collect information you provide directly, such as your GitHub username when using our tracker. We also collect usage data including pages visited and features used to improve our service.",
},
{
title: "How We Use Your Information",
content:
"We use collected information to provide and improve our services, respond to your requests, and send relevant updates. We do not sell your personal information to third parties.",
},
{
title: "Data Storage & Security",
content:
"Your data is stored securely using industry-standard encryption. We retain your information only as long as necessary to provide our services or as required by law.",
},
{
title: "Third-Party Services",
content:
"GitHub Tracker uses the public GitHub API to fetch repository and contribution data. We are not responsible for GitHub's privacy practices. Please review GitHub's Privacy Policy for more information.",
},
{
title: "Cookies",
content:
"We use session cookies to manage authentication. These cookies are essential for the service to function and are deleted when you close your browser or log out.",
},
{
title: "Your Rights",
content:
"You have the right to access, correct, or delete your personal data at any time. To exercise these rights, please contact us through the Contact page.",
},
{
title: "Changes to This Policy",
content:
"We may update this Privacy Policy from time to time. We will notify you of significant changes by posting the new policy on this page with an updated date.",
},
];

const PrivacyPolicy = () => (
<LegalPageLayout
title="Privacy Policy"
intro="At GitHub Tracker, we are committed to protecting your privacy. This policy explains what information we collect, how we use it, and your rights regarding your data."
sections={sections}
/>
);

export default PrivacyPolicy;
49 changes: 49 additions & 0 deletions src/pages/TermsAndConditions/TermsAndConditions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import LegalPageLayout from "../../components/legal/LegalPageLayout";

const sections = [
{
title: "Acceptance of Terms",
content:
"By accessing or using GitHub Tracker, you agree to be bound by these Terms and Conditions. If you do not agree to these terms, please do not use our service.",
},
{
title: "Use of Service",
content:
"GitHub Tracker is provided for personal and professional use to track GitHub activity. You agree not to misuse the service, attempt unauthorized access, or use it for any unlawful purpose.",
},
{
title: "GitHub API Usage",
content:
"Our service relies on the public GitHub API. Usage is subject to GitHub's Terms of Service and API rate limits. We are not affiliated with or endorsed by GitHub, Inc.",
},
{
title: "User Accounts",
content:
"You are responsible for maintaining the confidentiality of your account credentials. You agree to notify us immediately of any unauthorized use of your account.",
},
{
title: "Intellectual Property",
content:
"All content, design, and code within GitHub Tracker is the intellectual property of its contributors. You may not reproduce or distribute any part of the service without explicit permission.",
},
{
title: "Disclaimer of Warranties",
content:
"GitHub Tracker is provided as-is without warranties of any kind. We do not guarantee uninterrupted or error-free service and are not liable for any data loss or damages.",
},
{
title: "Changes to Terms",
content:
"We reserve the right to modify these terms at any time. Continued use of the service after changes constitutes your acceptance of the new terms.",
},
];

const TermsAndConditions = () => (
<LegalPageLayout
title="Terms & Conditions"
intro="Please read these Terms and Conditions carefully before using GitHub Tracker. These terms govern your use of our service and constitute a legal agreement between you and GitHub Tracker."
sections={sections}
/>
);

export default TermsAndConditions;
Loading