refactor(share-modal): tokenize interior palette (cleanup Brief 2) #129
1 changed files with 141 additions and 36 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Modal } from './ui';
|
import { Modal, Button } from './ui';
|
||||||
|
|
||||||
export default function ShareModal({
|
export default function ShareModal({
|
||||||
isOpen,
|
isOpen,
|
||||||
|
|
@ -136,31 +136,55 @@ export default function ShareModal({
|
||||||
<Modal open={isOpen} onClose={onClose} title="Share" size="md">
|
<Modal open={isOpen} onClose={onClose} title="Share" size="md">
|
||||||
<>
|
<>
|
||||||
{/* Public Access Toggle */}
|
{/* Public Access Toggle */}
|
||||||
<div className="mb-6 p-4 border rounded-lg">
|
<div
|
||||||
|
className="mb-6 p-4 rounded-xl"
|
||||||
|
style={{
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
backgroundColor: 'var(--bg-secondary)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div className="flex items-start space-x-3">
|
<div className="flex items-start space-x-3">
|
||||||
<svg className="w-5 h-5 text-gray-400 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg
|
||||||
|
className="w-5 h-5 mt-0.5"
|
||||||
|
style={{ color: 'var(--text-secondary)' }}
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.102m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.102m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
|
||||||
</svg>
|
</svg>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="font-medium text-gray-900">Public access</h3>
|
<h3 className="font-medium" style={{ color: 'var(--text-primary)' }}>
|
||||||
<p className="text-sm text-gray-500">Anyone with a link can view</p>
|
Public access
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm" style={{ color: 'var(--text-secondary)' }}>
|
||||||
|
Anyone with a link can view
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={onTogglePublic}
|
onClick={onTogglePublic}
|
||||||
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
|
className="relative inline-flex h-6 w-11 items-center rounded-full transition-colors"
|
||||||
isPublic ? 'bg-blue-600' : 'bg-gray-200'
|
style={{
|
||||||
}`}
|
backgroundColor: isPublic
|
||||||
|
? 'var(--accent-ember)'
|
||||||
|
: 'var(--bg-tertiary)',
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
|
className={`inline-block h-4 w-4 transform rounded-full transition-transform ${
|
||||||
isPublic ? 'translate-x-6' : 'translate-x-1'
|
isPublic ? 'translate-x-6' : 'translate-x-1'
|
||||||
}`}
|
}`}
|
||||||
|
style={{ backgroundColor: 'rgb(255, 255, 255)' }}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-gray-500 mt-1">
|
<p
|
||||||
|
className="text-sm mt-1"
|
||||||
|
style={{ color: 'var(--text-secondary)' }}
|
||||||
|
>
|
||||||
This list will be available in the community.
|
This list will be available in the community.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -175,9 +199,21 @@ export default function ShareModal({
|
||||||
placeholder="Add emails or people"
|
placeholder="Add emails or people"
|
||||||
value={searchQuery}
|
value={searchQuery}
|
||||||
onChange={(e) => handleSearch(e.target.value)}
|
onChange={(e) => handleSearch(e.target.value)}
|
||||||
className="w-full px-4 py-3 pl-10 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full px-4 py-3 pl-10 rounded-xl focus:ring-2 focus:border-transparent"
|
||||||
|
style={{
|
||||||
|
border: '1px solid var(--input-border)',
|
||||||
|
backgroundColor: 'var(--input-bg)',
|
||||||
|
color: 'var(--text-primary)',
|
||||||
|
'--tw-ring-color': 'var(--accent-ember)',
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<svg className="w-5 h-5 text-gray-400 absolute left-3 top-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg
|
||||||
|
className="w-5 h-5 absolute left-3 top-3.5"
|
||||||
|
style={{ color: 'var(--text-secondary)' }}
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -253,27 +289,52 @@ export default function ShareModal({
|
||||||
|
|
||||||
{/* Current Permissions */}
|
{/* Current Permissions */}
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<p className="text-sm text-gray-700 mb-3">
|
<p
|
||||||
|
className="text-sm mb-3"
|
||||||
|
style={{ color: 'var(--text-secondary)' }}
|
||||||
|
>
|
||||||
Only those invited can view or collaborate on this list.
|
Only those invited can view or collaborate on this list.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{/* Current User */}
|
{/* Current User */}
|
||||||
{currentUser && (
|
{currentUser && (
|
||||||
<div className="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
|
<div
|
||||||
|
className="flex items-center justify-between p-3 rounded-xl"
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'var(--bg-secondary)',
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<div className="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center mr-3">
|
<div
|
||||||
|
className="w-8 h-8 rounded-full flex items-center justify-center mr-3"
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
'linear-gradient(135deg, var(--accent-ember) 0%, var(--accent-flame) 100%)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<span className="text-white text-sm font-bold">
|
<span className="text-white text-sm font-bold">
|
||||||
{currentUser.email.charAt(0).toUpperCase()}
|
{currentUser.email.charAt(0).toUpperCase()}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="font-medium text-gray-900">
|
<div
|
||||||
|
className="font-medium"
|
||||||
|
style={{ color: 'var(--text-primary)' }}
|
||||||
|
>
|
||||||
{currentUser.email} (You)
|
{currentUser.email} (You)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm text-gray-500 px-2 py-1 bg-white rounded border">
|
<span
|
||||||
|
className="text-sm px-2 py-1 rounded-xl"
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'var(--bg-tertiary)',
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
Owner
|
Owner
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -281,20 +342,45 @@ export default function ShareModal({
|
||||||
|
|
||||||
{/* Invited Users */}
|
{/* Invited Users */}
|
||||||
{invitedUsers.map((permission) => (
|
{invitedUsers.map((permission) => (
|
||||||
<div key={permission.id} className="flex items-center justify-between p-3 border rounded-lg">
|
<div
|
||||||
|
key={permission.id}
|
||||||
|
className="flex items-center justify-between p-3 rounded-xl"
|
||||||
|
style={{
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
backgroundColor: 'var(--bg-secondary)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<div className="w-8 h-8 bg-gray-400 rounded-full flex items-center justify-center mr-3">
|
<div
|
||||||
<span className="text-white text-sm font-bold">
|
className="w-8 h-8 rounded-full flex items-center justify-center mr-3"
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'var(--bg-tertiary)',
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="text-sm font-bold"
|
||||||
|
style={{ color: 'var(--text-primary)' }}
|
||||||
|
>
|
||||||
{permission.user_email?.charAt(0).toUpperCase() || '?'}
|
{permission.user_email?.charAt(0).toUpperCase() || '?'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="font-medium text-gray-900">
|
<div
|
||||||
|
className="font-medium"
|
||||||
|
style={{ color: 'var(--text-primary)' }}
|
||||||
|
>
|
||||||
{permission.user_email || 'Unknown User'}
|
{permission.user_email || 'Unknown User'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm text-gray-500 px-2 py-1 bg-gray-100 rounded">
|
<span
|
||||||
|
className="text-sm px-2 py-1 rounded-xl"
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'var(--bg-tertiary)',
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
{permission.role === 'editor' ? 'Collaborator' : 'Viewer'}
|
{permission.role === 'editor' ? 'Collaborator' : 'Viewer'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -309,18 +395,29 @@ export default function ShareModal({
|
||||||
type="text"
|
type="text"
|
||||||
value={window.location.href}
|
value={window.location.href}
|
||||||
readOnly
|
readOnly
|
||||||
className="flex-1 px-3 py-2 bg-gray-50 border border-gray-300 rounded-lg text-sm text-gray-600"
|
className="flex-1 px-3 py-2 rounded-xl text-sm"
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'var(--input-bg)',
|
||||||
|
border: '1px solid var(--input-border)',
|
||||||
|
color: 'var(--text-primary)',
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<button
|
{copySuccess ? (
|
||||||
onClick={handleCopyLink}
|
<span
|
||||||
className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
|
className="px-4 py-2 rounded-xl text-sm font-medium inline-flex items-center"
|
||||||
copySuccess
|
style={{
|
||||||
? 'bg-green-100 text-green-800 border border-green-200'
|
backgroundColor: 'var(--bg-secondary)',
|
||||||
: 'bg-blue-600 text-white hover:bg-blue-700'
|
color: 'var(--accent-flame)',
|
||||||
}`}
|
border: '1px solid var(--accent-ember)',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{copySuccess ? 'Copied!' : 'Copy link'}
|
Copied!
|
||||||
</button>
|
</span>
|
||||||
|
) : (
|
||||||
|
<Button variant="primary" onClick={handleCopyLink}>
|
||||||
|
Copy link
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -338,7 +435,10 @@ export default function ShareModal({
|
||||||
className="flex flex-col items-center p-3 rounded-xl border nav-item-hover transition-colors"
|
className="flex flex-col items-center p-3 rounded-xl border nav-item-hover transition-colors"
|
||||||
style={{ borderColor: 'var(--border)' }}
|
style={{ borderColor: 'var(--border)' }}
|
||||||
>
|
>
|
||||||
<div className="w-8 h-8 mb-2 text-gray-600">
|
<div
|
||||||
|
className="w-8 h-8 mb-2"
|
||||||
|
style={{ color: 'var(--text-secondary)' }}
|
||||||
|
>
|
||||||
{social.icon === 'twitter' && (
|
{social.icon === 'twitter' && (
|
||||||
<svg viewBox="0 0 24 24" fill="currentColor">
|
<svg viewBox="0 0 24 24" fill="currentColor">
|
||||||
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/>
|
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/>
|
||||||
|
|
@ -360,7 +460,12 @@ export default function ShareModal({
|
||||||
</svg>
|
</svg>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs text-gray-600">{social.name}</span>
|
<span
|
||||||
|
className="text-xs"
|
||||||
|
style={{ color: 'var(--text-secondary)' }}
|
||||||
|
>
|
||||||
|
{social.name}
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue