Skip to content
Merged
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: 3 additions & 1 deletion src/components/AboutPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,9 @@ const AboutPage: React.FC = () => {
Questions or want to learn more?
</p>
<a
href="mailto:hello@refactron.dev"
href="https://cal.com/omsherikar/queries-refactron"
target="_blank"
rel="noopener noreferrer"
className="inline-block px-8 py-4 bg-transparent border border-white/10 text-white rounded-xl hover:bg-white/5 hover:border-white/20 transition-all font-medium font-space"
>
Get in touch with us
Expand Down
92 changes: 91 additions & 1 deletion src/components/AccountSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { motion } from 'framer-motion';
import { User, Lock, AlertTriangle, Check } from 'lucide-react';
import { User, Lock, AlertTriangle, Check, Github } from 'lucide-react';
import { useAuth } from '../hooks/useAuth';
import DashboardLayout from './DashboardLayout';
import { getApiBaseUrl } from '../utils/urlUtils';
Expand All @@ -26,9 +26,36 @@ const AccountSettings: React.FC = () => {
text: string;
} | null>(null);

// GitHub disconnect state
const [disconnecting, setDisconnecting] = useState(false);
const [confirmDisconnect, setConfirmDisconnect] = useState(false);
const [disconnectError, setDisconnectError] = useState('');

const apiBase = getApiBaseUrl();
const token = localStorage.getItem('accessToken');

const handleDisconnectGitHub = async () => {
setDisconnecting(true);
setDisconnectError('');
try {
const res = await fetch(`${apiBase}/api/auth/disconnect/github`, {
method: 'POST',
headers: { Authorization: `Bearer ${token}` },
});
const data = await res.json();
if (res.ok && data.success) {
updateUser(data.user);
setConfirmDisconnect(false);
} else {
setDisconnectError(data.message ?? 'Failed to disconnect GitHub.');
}
} catch {
setDisconnectError('Network error. Please try again.');
} finally {
setDisconnecting(false);
}
};

const handleSaveProfile = async (e: React.FormEvent) => {
e.preventDefault();
if (!fullName.trim()) return;
Expand Down Expand Up @@ -280,6 +307,69 @@ const AccountSettings: React.FC = () => {
)}
</section>

{/* GitHub Integration Section */}
<section className="rounded-2xl border border-white/[0.08] bg-white/[0.02] p-6 mb-4">
<div className="flex items-center gap-2 mb-5">
<Github className="h-3.5 w-3.5 text-neutral-600" />
<p className="text-xs font-bold uppercase tracking-widest text-neutral-600">
GitHub Integration
</p>
</div>

<div className="flex items-center justify-between">
<div className="flex items-center gap-2.5">
<span
className={`h-2 w-2 rounded-full ${
user?.githubConnected ? 'bg-emerald-500' : 'bg-neutral-700'
}`}
/>
<span className="text-sm text-neutral-400">
{user?.githubConnected ? 'Connected' : 'Not connected'}
</span>
</div>

{user?.githubConnected && !confirmDisconnect && (
<button
onClick={() => setConfirmDisconnect(true)}
className="inline-flex items-center gap-2 rounded-xl border border-white/[0.10] bg-white/[0.04] px-4 py-2 text-sm font-medium text-neutral-300 transition-colors hover:border-white/20 hover:bg-white/[0.07] hover:text-white"
>
Disconnect
</button>
)}
</div>

{confirmDisconnect && (
<div className="mt-4 rounded-xl border border-amber-500/20 bg-amber-500/[0.04] px-4 py-3 space-y-3">
<p className="text-sm text-amber-400/80">
Are you sure? This will unlink your GitHub account from
Refactron.
</p>
{disconnectError && (
<p className="text-sm text-red-400">{disconnectError}</p>
)}
<div className="flex items-center gap-2">
<button
onClick={handleDisconnectGitHub}
disabled={disconnecting}
className="inline-flex items-center gap-2 rounded-xl border border-red-500/30 bg-red-500/[0.06] px-4 py-2 text-sm font-medium text-red-400 transition-colors hover:border-red-500/50 hover:text-red-300 disabled:opacity-40 disabled:cursor-not-allowed"
>
{disconnecting ? 'Disconnecting…' : 'Yes, disconnect'}
</button>
<button
onClick={() => {
setConfirmDisconnect(false);
setDisconnectError('');
}}
disabled={disconnecting}
className="inline-flex items-center gap-2 rounded-xl border border-white/[0.10] bg-white/[0.04] px-4 py-2 text-sm font-medium text-neutral-400 transition-colors hover:text-white disabled:opacity-40 disabled:cursor-not-allowed"
>
Cancel
</button>
</div>
</div>
)}
</section>

{/* Danger Zone */}
<section className="rounded-2xl border border-red-500/10 bg-red-500/[0.02] p-6">
<div className="flex items-center gap-2 mb-3">
Expand Down
4 changes: 3 additions & 1 deletion src/components/CaseStudiesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,9 @@ const CaseStudiesPage: React.FC = () => {
</p>
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
<a
href="/#early-access"
href="https://cal.com/omsherikar/queries-refactron"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center justify-center gap-2 bg-white text-black font-semibold px-8 py-4 rounded-xl hover:bg-neutral-200 transition-all duration-300"
>
Book a Session
Expand Down
Loading
Loading