feat: Implement Share Modal for document sharing functionality

- Added ShareModal component to manage user and link sharing for documents.
- Created AuthContext to handle user authentication state and token management.
- Updated useYjsDocument hook to support sharing via tokens.
- Enhanced Yjs document creation to include user information and authentication tokens.
- Introduced AuthCallback page to handle authentication redirects and token processing.
- Modified EditorPage and KanbanPage to include share functionality.
- Created LoginPage with Google and GitHub authentication options.
- Added styles for LoginPage.
- Defined types for authentication and sharing in respective TypeScript files.
This commit is contained in:
M1ngdaXie
2026-01-06 22:03:07 -08:00
parent 8ae7fd96e8
commit 0a5e6661f1
30 changed files with 1923 additions and 118 deletions

View File

@@ -1,12 +1,18 @@
import { useNavigate, useParams } from "react-router-dom";
import { useState } from "react";
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import Editor from "../components/Editor/Editor.tsx";
import UserList from "../components/Presence/UserList.tsx";
import ShareModal from "../components/Share/ShareModal.tsx";
import Navbar from "../components/Navbar.tsx";
import { useYjsDocument } from "../hooks/useYjsDocument.ts";
const EditorPage = () => {
const { id } = useParams<{ id: string }>();
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const { providers, synced } = useYjsDocument(id!);
const shareToken = searchParams.get('share') || undefined;
const { providers, synced } = useYjsDocument(id!, shareToken);
const [showShareModal, setShowShareModal] = useState(false);
if (!providers) {
return <div className="loading">Connecting...</div>;
@@ -14,10 +20,18 @@ const EditorPage = () => {
return (
<div className="editor-page">
<Navbar />
<div className="page-header">
<button onClick={() => navigate("/")}> Back to Home</button>
<div className="sync-status">
{synced ? "✓ Synced" : "⟳ Syncing..."}
<div className="header-actions">
<div className="sync-status">
{synced ? "✓ Synced" : "⟳ Syncing..."}
</div>
{!shareToken && (
<button className="share-btn" onClick={() => setShowShareModal(true)}>
Share
</button>
)}
</div>
</div>
@@ -29,6 +43,10 @@ const EditorPage = () => {
<UserList awareness={providers.awareness} />
</div>
</div>
{showShareModal && (
<ShareModal documentId={id!} onClose={() => setShowShareModal(false)} />
)}
</div>
);
};