Skip to content
Closed
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
34 changes: 34 additions & 0 deletions frontend/app/add-sphere-member/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Header from '../components/Header'
import SecondStepper from '../components/SecondStepper'
import AddShereMembers from '../components/AddSphereMembers'
import ConfigureThreshold from '../components/ConfigureThreshold'

export default function Home() {
return (
<div className="min-h-screen bg-black text-white">
<Header />
{/* Main Content */}
<div className="flex flex-col items-center pt-16 sm:pt-20 md:pt-24 pb-6 sm:pb-8">
{/* Stepper */}
<SecondStepper />

{/* Heading and Description */}
<div className="w-full px-4 sm:w-[456px]">
<h1 className="text-2xl sm:text-3xl md:text-4xl font-bold mb-3 sm:mb-4 text-center">
Add Members to a Multisig Vault
</h1>
<p className="text-gray-400 text-sm sm:text-base text-center mb-6 sm:mb-8 max-w-lg">
Add your team members & customize security settings to fit your team
needs.
</p>
</div>

{/* Sphere Review Card and Members Threshold */}
<div className="w-full px-4 flex flex-col items-center space-y-4">
<AddShereMembers />
<ConfigureThreshold />
</div>
</div>
</div>
)
}
70 changes: 70 additions & 0 deletions frontend/app/components/AddSphereMembers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
'use client'

import React, { useState } from 'react'
import Image from 'next/image'
import Delete from '../../public/Images/trash-bin.png'

const AddSphereMembers = () => {
const [members, setMembers] = useState([
'elbbababaahhajaagsahv77278191912a',
'',
])

const addMember = () => {
setMembers([...members, ''])
}

const removeMember = (index: number) => {
setMembers(members.filter((_, i) => i !== index))
}

const updateMember = (index: number, value: string) => {
const updatedMembers = [...members]
updatedMembers[index] = value
setMembers(updatedMembers)
}

return (
<div className="w-full max-w-md">
<h1 className="text-lg font-semibold bg-gray-800 text-white rounded-t-lg mb-[-2] p-6">
Add Sphere Members
</h1>
<div className="w-full max-w-md bg-gray-900 rounded-b-lg p-6">
{/* Member List */}
{members.map((member, index) => (
<div key={index} className="mb-4">
<div className="flex items-center justify-between">
<label className="text-sm text-white mb-1">
Member {index + 1}
</label>
{members.length > 1 && (
<button
onClick={() => removeMember(index)}
className="text-gray-400 hover:text-gray-200"
>
<Image src={Delete} alt=""></Image>
</button>
)}
</div>
<input
type="text"
value={member}
onChange={(e) => updateMember(index, e.target.value)}
placeholder="Enter team member’s address"
className="w-full bg-gray-800 text-white text-sm rounded-lg p-2 border border-gray-700 focus:outline-none focus:border-purple-600"
/>
</div>
))}

<button
onClick={addMember}
className="flex items-center bg-gray-800 w-full p-4 text-center items-center justify-center rounded-lg hover:text-purple-500 text-sm"
>
<span className="mr-1">+</span> Add Member
</button>
</div>
</div>
)
}

export default AddSphereMembers
49 changes: 49 additions & 0 deletions frontend/app/components/ConfigureThreshold.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use client'

import React, { useState } from 'react'

const ConfigureThreshold = () => {
const [threshold, setThreshold] = useState(1) // Default value of 1

// Handle slider change
const handleThresholdChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setThreshold(Number(e.target.value))
}

return (
<div className="w-full max-w-md bg-gray-900 rounded-lg p-6">
{/* Title */}
<h1 className="text-lg font-semibold text-white mb-2">
Configure Threshold
</h1>

{/* Description */}
<p className="text-sm text-gray-400 mb-6">
Please select the amount of approvals needed to confirm a transaction.
</p>

{/* Slider */}
<div className="mb-6">
<input
type="range"
min="1"
max="2"
value={threshold}
onChange={handleThresholdChange}
className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer"
/>
<div className="flex justify-between mt-2">
<span className="text-sm text-gray-400">1</span>
<span className="text-sm text-gray-400">2</span>
</div>
</div>

{/* Continue Button */}
<button className="w-full py-2 bg-white text-black rounded-lg hover:bg-gray-200">
Continue
</button>
</div>
)
}

export default ConfigureThreshold
40 changes: 40 additions & 0 deletions frontend/app/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'
import Image from 'next/image'
import Logo from '@/public/Images/spherrelogo.png'

const Header = () => {
return (
<header className="bg-black text-white flex justify-between items-center p-4 fixed top-0 w-full z-10">
{/* Logo */}
<div className="flex items-center">
<div className="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center mr-2">
<Image src={Logo} alt=""></Image>
</div>
<h1 className="text-lg font-semibold">Sphere</h1>
</div>

{/* Navigation Links */}
<nav className="hidden md:flex space-x-8 lg:ml-16">
<a href="#" className="text-gray-400 text-white">
Docs
</a>
<a href="#" className="text-gray-400 text-white">
Telegram
</a>
<a href="#" className="text-gray-400 text-white">
Twitter
</a>
</nav>

{/* User Profile */}
<div className="flex items-center w-[188px] h-[50px] gap-[8px] rounded-[50px] border-[1.5px] p-[10px_20px] border border-white border-[1.5px]">
<div className="w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center mr-2">
<span className="text-gray-400">👤</span>
</div>
<span className="text-white text-sm">0x60...5542</span>
</div>
</header>
)
}

export default Header
43 changes: 43 additions & 0 deletions frontend/app/components/MembersThreshold.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'
import Image from 'next/image'
import Users from '@/public/Images/users-group.png'
import Book from '@/public/Images/fluent-book.png'

const MembersThreshold = ({ members = 3, threshold = '1/2' }) => {
return (
<div className="w-full max-w-md bg-[#1C1D1F] rounded-[10px] p-6 mt-4">
<div className="w-full flex gap-4 mb-6">
<div className="bg-[#272729] w-[281px] h-[139px] rounded-[10px] p-4 flex items-center justify-between">
<div className="flex flex-col items-start gap-[40px]">
<Image src={Users} alt=""></Image>
<p className="text-sm text-gray-400">Members</p>
</div>
<p className="font-['Nunito_Sans'] font-bold text-[40px] leading-[54.56px] tracking-[-0.8px] text-right">
{members}
</p>
</div>

<div className="bg-[#272729] w-[281px] h-[139px] rounded-[10px] p-4 flex items-center justify-between">
<div className="flex flex-col items-start gap-[40px]">
<Image src={Book} alt=""></Image>
<p className="text-sm text-gray-400">Threshold</p>
</div>
<p className="font-['Nunito_Sans'] font-bold text-[40px] leading-[54.56px] tracking-[-0.8px] text-right">
{threshold}
</p>
</div>
</div>

<div className="flex justify-between">
<button className="w-1/2 mr-2 py-2 bg-[#272729] text-white rounded-lg hover:bg-gray-600">
Back
</button>
<button className="w-1/2 ml-2 py-2 bg-white text-black rounded-lg hover:bg-gray-200">
Confirm
</button>
</div>
</div>
)
}

export default MembersThreshold
35 changes: 35 additions & 0 deletions frontend/app/components/SecondStepper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react'

const SecondStepper = () => {
return (
<div className="flex items-center justify-center space-x-4 mt-16 mb-8">
{/* Step 1 */}
<div className="flex flex-col items-center">
<div className="w-8 h-8 bg-gray-600 rounded-full flex items-center justify-center text-white">
1
</div>
<span className="text-gray-400 text-sm mt-2">Account Details</span>
</div>
<div className="w-12 h-0.5 bg-gray-600"></div>

{/* Step 2 */}
<div className="flex flex-col items-center">
<div className="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white">
2
</div>
<span className="text-gray-400 text-sm mt-2">Member & Threshold</span>
</div>
<div className="w-12 h-0.5 bg-gray-600"></div>

{/* Step 3 (Active) */}
<div className="flex flex-col items-center">
<div className="w-8 h-8 bg-gray-600 rounded-full flex items-center justify-center text-white">
3
</div>
<span className="text-white text-sm mt-2">Confirm & Setup</span>
</div>
</div>
)
}

export default SecondStepper
66 changes: 66 additions & 0 deletions frontend/app/components/SphereAccountReview.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use client'
import React, { useState } from 'react'
import Image from 'next/image'
import Fill from '@/public/Images/sphere-fill.png'
const SphereAccountReview = ({
groupName = 'Backstage Boys',
members = 'Deon, John and Joshua',
deployFee = '~0.0530 SOL',
}) => {
const [showTooltip, setShowTooltip] = useState(false)

return (
<div className="">
<h1 className="text-lg font-semibold bg-[#272729] h-[62px] rounded-t-[10px] text-white py-4 px-6">
Review your Sphere Account
</h1>
<div className="w-full max-w-md bg-[#1C1D1F] rounded-b-lg p-6">
<div className="flex items-center mb-4">
<div className="w-10 h-10 bg-gray-700 rounded-full mr-3 flex items-center justify-center">
<Image src={Fill} alt=""></Image>
</div>
<h2 className="font-['Nunito_Sans'] font-bold text-[32px] leading-[43.65px] tracking-[-2%]">
{groupName}
</h2>
</div>
<p className="text-sm text-gray-400">Members: {members}</p>

<div className="mb-4">
<div className="flex gap-[44px] py-3 items-center">
<p className="text-sm text-white">
Deploy Fee{' '}
<span
className="text-gray-400 cursor-pointer ml-2"
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
>
</span>
</p>
<p className="font-['Nunito_Sans'] font-bold text-[32px] leading-[43.65px] tracking-[-0.11px] text-white">
{deployFee}
</p>
</div>
{showTooltip && (
<div className="absolute bg-gray-800 text-white text-xs p-2 rounded-lg mt-1">
More info about the deploy fee will go here.
</div>
)}
<p className="text-xs text-gray-500 mt-1">
<span
className="text-gray-400 mr-2 cursor-pointer"
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
>
</span>
This info section should explain why there is a {deployFee} deploy
fee. Please the information should be quite detailed.
</p>
</div>
</div>
</div>
)
}

export default SphereAccountReview
35 changes: 35 additions & 0 deletions frontend/app/components/Stepper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react'

const Stepper = () => {
return (
<div className="flex items-center justify-center space-x-4 mt-16 mb-8">
{/* Step 1 */}
<div className="flex flex-col items-center">
<div className="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white">
1
</div>
<span className="text-gray-400 text-sm mt-2">Account Details</span>
</div>
<div className="w-12 h-0.5 bg-gray-600"></div>

{/* Step 2 */}
<div className="flex flex-col items-center">
<div className="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white">
2
</div>
<span className="text-gray-400 text-sm mt-2">Member & Threshold</span>
</div>
<div className="w-12 h-0.5 bg-gray-600"></div>

{/* Step 3 (Active) */}
<div className="flex flex-col items-center">
<div className="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white">
3
</div>
<span className="text-white text-sm mt-2">Confirm & Setup</span>
</div>
</div>
)
}

export default Stepper
Loading