diff --git a/.build.hash b/.build.hash index f29013c..3117423 100644 --- a/.build.hash +++ b/.build.hash @@ -1 +1 @@ -be65400be96a473622c09b3df6073c5837dacc82-372bcf506971f56c4911b429b9f5de5bc37ed008-e9eccd451b778829eb2f2c9752c670b707e1268b +c5704005f291ecf264cdc92403119e7db5831e61-372bcf506971f56c4911b429b9f5de5bc37ed008-e9eccd451b778829eb2f2c9752c670b707e1268b diff --git a/src/App.js b/src/App.js index 8932074..f236c21 100644 --- a/src/App.js +++ b/src/App.js @@ -48,6 +48,8 @@ import * as safeLocal from './utils/safeLocal.js'; import VerificationGate from './components/VerificationGate.js'; import Verify from './components/Verify.js'; import { initNetObserver } from './utils/net.js'; +import PrivacyPolicy from './components/PrivacyPolicy.js'; +import TermsOfService from './components/TermsOfService.js'; @@ -225,7 +227,9 @@ if (loggingOut) return; location.pathname.startsWith('/reset-password') || location.pathname === '/signin' || location.pathname === '/signup' || - location.pathname === '/forgot-password' + location.pathname === '/forgot-password' || + location.pathname === '/privacy' || + location.pathname === '/terms' ) { try { localStorage.removeItem('id'); } catch {} setIsAuthenticated(false); @@ -260,7 +264,9 @@ if (loggingOut) return; p === '/signup' || p === '/forgot-password' || p.startsWith('/reset-password') || - p === '/paywall'; + p === '/paywall' || + p === '/privacy' || + p === '/terms'; if (!onPublic) navigate('/signin?session=expired', { replace: true }); } finally { if (!cancelled) setIsLoading(false); @@ -372,7 +378,7 @@ const cancelLogout = () => { {/* Header */}

- AptivaAI - Career Guidance Platform + AptivaAI - Career Guidance Platform

{/* Mobile hamburger */} @@ -836,6 +842,8 @@ const cancelLogout = () => { } /> } /> + } /> + } /> {/* Authenticated routes */} {isAuthenticated && ( @@ -874,6 +882,22 @@ const cancelLogout = () => { + {/* Minimal global footer with legal links (always visible) */} +
+
+ + © {new Date().getFullYear()} AptivaAI LLC ·{' '} + + Privacy Policy + {' '} + ·{' '} + + Terms of Service + + +
+
+ {/* Support modal mounted once at root so it centers correctly on desktop & mobile */} { setShown(true); }; + const onCopy = async () => { + try { + await navigator.clipboard.writeText(addr); + setCopied(true); + setTimeout(() => setCopied(false), 1500); + } catch {} + }; + return ( + + {!shown ? ( + + ) : ( + + )} + + ); +} + +function PrivacyPolicy() { + return ( +
+
+

Privacy Policy

+

+ Effective Date: 9/19/25 +

+ +

Introduction

+

+ AptivaAI LLC (“AptivaAI,” “we,” “our,” or “us”) respects your privacy. + This Privacy Policy explains what information we collect, how we use it, + and your rights. +

+ +

Information We Collect

+
    +
  • Account information (username, password, profile details).
  • +
  • + Payment information handled by third-party payment processors ++ (we do not store full card details). +
  • +
  • + Messaging information (phone/email for notifications) handled by communications providers. +
  • +
  • Career and education data you enter into your profile.
  • +
  • + Technical information: necessary cookies and local storage (for + authentication, security, and preferences). +
  • +
+

+ We do not use third-party analytics or marketing + cookies at this time. If we add them later, you’ll be able to opt in + before they’re used. +

+ +

How We Use Information

+
    +
  • Provide and improve AptivaAI’s services.
  • +
  • Process subscription payments.
  • +
  • Securely authenticate your account.
  • +
  • Deliver optional notifications (if enabled).
  • +
+

+ We do not sell your personal information. +

+ +

Cookies and Local Storage

+

+ Necessary cookies/local storage are always used for authentication and + site functionality. Optional cookies (analytics, marketing) are not + currently in use. If we add them later, we’ll update this policy and + request your consent. +

+ +

Data Sharing

+

+ We only share information with providers required to run AptivaAI. + These providers are bound by their + own security/privacy obligations. We do not sell or rent your data. +

+ +

Data Security

+

+ We take security seriously with encryption, strict access controls, and + logging. While no system is 100% secure, we continually work to protect + your data. +

+ +

Your Rights

+

+ Depending on your location, you may have the right to access, correct, + or delete your personal data; opt out of optional cookies (when added); + or cancel your account. To exercise your rights, contact us at{' '} + . +

+ +

Updates

+

+ We may update this Privacy Policy from time to time. If we make + significant changes, we’ll notify you in the app or by email. +

+ +

Contact

+

+ AptivaAI LLC
+ Email: +

+
+
+ ); +} + +export default PrivacyPolicy; diff --git a/src/components/SignIn.js b/src/components/SignIn.js index f4f5f48..2a27ba0 100644 --- a/src/components/SignIn.js +++ b/src/components/SignIn.js @@ -10,6 +10,7 @@ function SignIn({ setIsAuthenticated, setUser }) { const passwordRef = useRef(''); const [error, setError] = useState(''); const [showSessionExpiredMsg, setShowSessionExpiredMsg] = useState(false); + const [showConsent, setShowConsent] = useState(false); const location = useLocation(); useEffect(() => { @@ -19,6 +20,33 @@ function SignIn({ setIsAuthenticated, setUser }) { } }, [location.search]); + + // ──────────────────────────────────────────────────────────── + // Consent banner (opt-in; necessary only always on) + // Stored in safeLocal under 'cookieConsent' + // ──────────────────────────────────────────────────────────── + useEffect(() => { + const existing = safeLocal.getItem('cookieConsent'); // {version, necessary, ts} + if (!existing) { + setShowConsent(true); + } else { + // expose globally for any script that checks it + window.__aptivaConsent = existing; + } + }, []); + + const saveConsent = () => { + const payload = { + version: 1, + necessary: true, + ts: Date.now(), + }; + safeLocal.setItem('cookieConsent', payload); + window.__aptivaConsent = payload; // allow other modules to read without storage hit + setShowConsent(false); + }; + + const handleSignIn = async (event) => { event.preventDefault(); setError(''); @@ -92,7 +120,7 @@ function SignIn({ setIsAuthenticated, setUser }) { )}
{/* Wordmark (text-only) */} -
AptivaAI
+
AptivaAI

Sign In

Career guidance powered by data — enhanced by AI

@@ -143,6 +171,44 @@ function SignIn({ setIsAuthenticated, setUser }) {
+ {/* ───────────────── Cookie Consent Banner (SignIn only) ───────────────── */} + {showConsent && ( +
+
+
+

Cookies & Privacy

+

+ We only use necessary cookies to run AptivaAI + (session/auth and basic preferences). By continuing, you consent to these necessary cookies. +

+
+ +
+ + Privacy Policy + + + Terms of Service + +
+
+ +
+
+
+ )} + {/* ─────────────────────────────────────────────────────────────────────── */} ); } diff --git a/src/components/TermsOfService.js b/src/components/TermsOfService.js new file mode 100644 index 0000000..59c7393 --- /dev/null +++ b/src/components/TermsOfService.js @@ -0,0 +1,117 @@ +import React, { useState } from 'react'; + +function EmailReveal({ className = '' }) { + const [shown, setShown] = useState(false); + const [copied, setCopied] = useState(false); + const u = 'support'; + const d = 'aptivaai.com'; + const addr = `${u}@${d}`; + const onReveal = () => { setShown(true); }; + const onCopy = async () => { + try { + await navigator.clipboard.writeText(addr); + setCopied(true); + setTimeout(() => setCopied(false), 1500); + } catch {} + }; + return ( + + {!shown ? ( + + ) : ( + + )} + + ); +} + +function TermsOfService() { + return ( +
+
+

Terms of Service

+

Effective Date: 9/19/25

+ +

1. Acceptance of Terms

+

+ By accessing or using AptivaAI (“Service”), you agree to these Terms of Service (“Terms”). + If you do not agree, do not use the Service. +

+ +

2. Eligibility

+

+ You must be at least 16 years old, or the minimum age required by law in your jurisdiction, + to use AptivaAI. By using the Service, you represent that you meet this requirement. +

+ +

3. Accounts

+

+ You are responsible for maintaining the confidentiality of your account credentials and for + all activity under your account. Notify us immediately of any unauthorized use. +

+ +

4. Subscriptions & Payments

+

+ Some features require a paid subscription. Payments are processed securely by + third-party payment processors. Fees are non-refundable except as required by law. +

+ +

5. Acceptable Use

+

+ You agree not to misuse the Service, including but not limited to: attempting to disrupt or + overload our systems; scraping or reverse engineering; impersonating others; or submitting + false or misleading information. +

+ +

6. Intellectual Property

+

+ AptivaAI content, trademarks, and software are owned by AptivaAI LLC. You may not copy, + modify, or distribute our materials without written permission. +

+ +

7. Disclaimers

+

+ AptivaAI provides career guidance and financial planning tools for informational purposes. + We do not guarantee employment outcomes, admissions, or financial results. The Service is + provided “as is” without warranties of any kind. +

+ +

8. Limitation of Liability

+

+ To the fullest extent permitted by law, AptivaAI LLC is not liable for any indirect, + incidental, or consequential damages arising from your use of the Service. +

+ +

9. Termination

+

+ We may suspend or terminate your account if you violate these Terms or misuse the Service. + You may cancel your account at any time through your settings. +

+ +

10. Governing Law

+

+ These Terms are governed by the laws of the State of Georgia, USA, without regard to + conflict of laws. Disputes will be resolved in courts located in Cobb County, Georgia. +

+ +

11. Changes to Terms

+

+ We may update these Terms from time to time. If changes are material, we will notify you + through the Service or by email. Continued use means you accept the updated Terms. +

+ +

12. Contact Us

+

+ AptivaAI LLC
+ Email: +

+
+
+ ); +} + +export default TermsOfService; diff --git a/src/utils/safeLocal.js b/src/utils/safeLocal.js index 6b2372f..c7c16f1 100644 --- a/src/utils/safeLocal.js +++ b/src/utils/safeLocal.js @@ -8,6 +8,7 @@ const ALLOW = { lastPanel: 1 * 24 * 3600 * 1000, // 1d flagsVersion: 6 * 3600 * 1000, // 6h lastCareerName: 1 * 24 * 3600 * 1000, // 1d + cookieConsent: 365 * 24 * 3600 * 1000, // 1 year }; function _ns(k) { return `${NS}${k}`; }