feat: glass pill action bars in CreateSpace, CreateChannel, JoinSpace, and RolesPanel
This commit is contained in:
@@ -128,22 +128,26 @@ export function CreateChannelModal() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex justify-end gap-2">
|
<div className="sticky bottom-0 z-10 pointer-events-none">
|
||||||
|
<div className="flex justify-center pt-3 pb-1">
|
||||||
|
<div className="glass-bubble rounded-full px-3 py-2 flex items-center gap-3 pointer-events-auto">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={closeModal}
|
onClick={closeModal}
|
||||||
className="px-4 py-2 text-sm text-txt-secondary hover:text-txt-primary transition-colors"
|
className="px-3 py-1 text-sm text-txt-tertiary hover:text-txt-secondary transition-colors"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
className="px-4 py-2 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded transition-colors disabled:opacity-50"
|
className="px-3 py-1.5 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded-full transition-colors disabled:opacity-50"
|
||||||
>
|
>
|
||||||
{isLoading ? 'Creating...' : 'Create Channel'}
|
{isLoading ? 'Creating...' : 'Create Channel'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -238,22 +238,26 @@ export function CreateSpaceModal() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Actions */}
|
{/* Actions */}
|
||||||
<div className="flex justify-end gap-2">
|
<div className="sticky bottom-0 z-10 pointer-events-none">
|
||||||
|
<div className="flex justify-center pt-3 pb-1">
|
||||||
|
<div className="glass-bubble rounded-full px-3 py-2 flex items-center gap-3 pointer-events-auto">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
className="px-4 py-2 text-sm text-txt-secondary hover:text-txt-primary transition-colors"
|
className="px-3 py-1 text-sm text-txt-tertiary hover:text-txt-secondary transition-colors"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isLoading || uploadingIcon}
|
disabled={isLoading || uploadingIcon}
|
||||||
className="px-4 py-2 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded transition-colors disabled:opacity-50"
|
className="px-3 py-1.5 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded-full transition-colors disabled:opacity-50"
|
||||||
>
|
>
|
||||||
{isLoading ? 'Creating...' : 'Create'}
|
{isLoading ? 'Creating...' : 'Create'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
|||||||
@@ -155,22 +155,26 @@ export function JoinSpaceModal() {
|
|||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-end gap-2">
|
<div className="sticky bottom-0 z-10 pointer-events-none">
|
||||||
|
<div className="flex justify-center pt-3 pb-1">
|
||||||
|
<div className="glass-bubble rounded-full px-3 py-2 flex items-center gap-3 pointer-events-auto">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={closeModal}
|
onClick={closeModal}
|
||||||
className="px-4 py-2 text-sm text-txt-secondary hover:text-txt-primary transition-colors"
|
className="px-3 py-1 text-sm text-txt-tertiary hover:text-txt-secondary transition-colors"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isLoading || !inviteCode.trim()}
|
disabled={isLoading || !inviteCode.trim()}
|
||||||
className="px-4 py-2 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded transition-colors disabled:opacity-50"
|
className="px-3 py-1.5 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded-full transition-colors disabled:opacity-50"
|
||||||
>
|
>
|
||||||
{isLoading ? 'Joining...' : 'Join Space'}
|
{isLoading ? 'Joining...' : 'Join Space'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -199,31 +203,37 @@ export function JoinSpaceModal() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
<div className="sticky bottom-0 z-10 pointer-events-none">
|
||||||
|
<div className="flex justify-center pt-3 pb-1">
|
||||||
|
<div className="glass-bubble rounded-full px-3 py-2 flex items-center gap-3 pointer-events-auto">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => { setPhase('input'); setPassword(''); setError(''); }}
|
onClick={() => { setPhase('input'); setPassword(''); setError(''); }}
|
||||||
className="text-xs text-txt-tertiary hover:text-txt-secondary transition-colors"
|
className="px-3 py-1 text-sm text-txt-tertiary hover:text-txt-secondary transition-colors flex items-center gap-1"
|
||||||
>
|
>
|
||||||
|
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M15 19l-7-7 7-7" />
|
||||||
|
</svg>
|
||||||
Back
|
Back
|
||||||
</button>
|
</button>
|
||||||
<div className="flex gap-2">
|
<div className="w-px h-5 bg-white/10" />
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={closeModal}
|
onClick={closeModal}
|
||||||
className="px-4 py-2 text-sm text-txt-secondary hover:text-txt-primary transition-colors"
|
className="px-3 py-1 text-sm text-txt-tertiary hover:text-txt-secondary transition-colors"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isLoading || !password}
|
disabled={isLoading || !password}
|
||||||
className="px-4 py-2 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded transition-colors disabled:opacity-50"
|
className="px-3 py-1.5 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded-full transition-colors disabled:opacity-50"
|
||||||
>
|
>
|
||||||
{isLoading ? 'Connecting...' : 'Connect & Join'}
|
{isLoading ? 'Connecting...' : 'Connect & Join'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -258,31 +268,37 @@ export function JoinSpaceModal() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
<div className="sticky bottom-0 z-10 pointer-events-none">
|
||||||
|
<div className="flex justify-center pt-3 pb-1">
|
||||||
|
<div className="glass-bubble rounded-full px-3 py-2 flex items-center gap-3 pointer-events-auto">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => { setPhase('connect'); setFallbackPassword(''); setError(''); }}
|
onClick={() => { setPhase('connect'); setFallbackPassword(''); setError(''); }}
|
||||||
className="text-xs text-txt-tertiary hover:text-txt-secondary transition-colors"
|
className="px-3 py-1 text-sm text-txt-tertiary hover:text-txt-secondary transition-colors flex items-center gap-1"
|
||||||
>
|
>
|
||||||
|
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M15 19l-7-7 7-7" />
|
||||||
|
</svg>
|
||||||
Back
|
Back
|
||||||
</button>
|
</button>
|
||||||
<div className="flex gap-2">
|
<div className="w-px h-5 bg-white/10" />
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={closeModal}
|
onClick={closeModal}
|
||||||
className="px-4 py-2 text-sm text-txt-secondary hover:text-txt-primary transition-colors"
|
className="px-3 py-1 text-sm text-txt-tertiary hover:text-txt-secondary transition-colors"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isLoading || !fallbackUsername || !fallbackPassword}
|
disabled={isLoading || !fallbackUsername || !fallbackPassword}
|
||||||
className="px-4 py-2 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded transition-colors disabled:opacity-50"
|
className="px-3 py-1.5 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded-full transition-colors disabled:opacity-50"
|
||||||
>
|
>
|
||||||
{isLoading ? 'Logging in...' : 'Login & Join'}
|
{isLoading ? 'Logging in...' : 'Login & Join'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -113,10 +113,11 @@ export function RolesPanel({ spaceId }: RolesPanelProps) {
|
|||||||
<div className="p-2 bg-accent-rose/10 border border-accent-rose/30 rounded text-txt-danger text-sm">{error}</div>
|
<div className="p-2 bg-accent-rose/10 border border-accent-rose/30 rounded text-txt-danger text-sm">{error}</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<div className="sticky top-0 z-10 pointer-events-none pb-3">
|
||||||
<button
|
<button
|
||||||
onClick={handleCreateRole}
|
onClick={handleCreateRole}
|
||||||
disabled={creating}
|
disabled={creating}
|
||||||
className="flex items-center gap-1.5 px-3 py-1.5 bg-accent-primary hover:bg-accent-primary/80 text-white text-sm font-medium rounded transition-colors disabled:opacity-50"
|
className="glass-bubble rounded-full px-3 py-1.5 flex items-center gap-1.5 text-sm text-txt-primary hover:text-txt-secondary transition-colors pointer-events-auto disabled:opacity-50"
|
||||||
>
|
>
|
||||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
|
||||||
<line x1="12" y1="5" x2="12" y2="19" />
|
<line x1="12" y1="5" x2="12" y2="19" />
|
||||||
@@ -124,6 +125,7 @@ export function RolesPanel({ spaceId }: RolesPanelProps) {
|
|||||||
</svg>
|
</svg>
|
||||||
{creating ? 'Creating...' : 'Create Role'}
|
{creating ? 'Creating...' : 'Create Role'}
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
{sortedRoles.map((role) => {
|
{sortedRoles.map((role) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user