Skip to content
Open
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
90 changes: 45 additions & 45 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
NEXTAUTH_URL=http://localhost:3000
NEXT_PUBLIC_APP_URL=http://localhost:3000
AUTH_SECRET= # https://generate-secret.vercel.app/32

COMMUNITIES_CONFIG_URL=''

# Brevo
BREVO_API_KEY=
BREVO_SENDER_EMAIL=
BREVO_SENDER_NAME=

# Server Account
SERVER_PRIVATE_KEY=
SERVER_ACCOUNT_ADDRESS=

# Supabase top level
SUPABASE_URL=https://...
SUPABASE_ANON_KEY=...
SUPABASE_SERVICE_ROLE_KEY=...
SUPABASE_DB_PASSWORD=

# Supabase for chain 100 (Gnosis Chain)
SUPABASE_100_URL=https://...
SUPABASE_100_ANON_KEY=...
SUPABASE_100_SERVICE_ROLE_KEY=...

# Supabase for chain 137 (Polygon)
SUPABASE_137_URL=https://...
SUPABASE_137_ANON_KEY=...
SUPABASE_137_SERVICE_ROLE_KEY=...

# Supabase for chain 42220 (Celo)
SUPABASE_42220_URL=https://...
SUPABASE_42220_ANON_KEY=...
SUPABASE_42220_SERVICE_ROLE_KEY=...
SERVER_42220_ACCOUNT_ADDRESS=
SERVER_42220_WALLET_PRIVATE_KEY=


# Supabase for chain 8453 (Base)
SUPABASE_8453_URL=https://...
SUPABASE_8453_ANON_KEY=...
SUPABASE_8453_SERVICE_ROLE_KEY=...

# ONRAMP
NEXTAUTH_URL=http://localhost:3000
NEXT_PUBLIC_APP_URL=http://localhost:3000
AUTH_SECRET= # https://generate-secret.vercel.app/32
COMMUNITIES_CONFIG_URL=''
# Brevo
BREVO_API_KEY=
BREVO_SENDER_EMAIL=
BREVO_SENDER_NAME=
# Server Account
SERVER_PRIVATE_KEY=
SERVER_ACCOUNT_ADDRESS=
# Supabase top level
SUPABASE_URL=https://...
SUPABASE_ANON_KEY=...
SUPABASE_SERVICE_ROLE_KEY=...
SUPABASE_DB_PASSWORD=
# Supabase for chain 100 (Gnosis Chain)
SUPABASE_100_URL=https://...
SUPABASE_100_ANON_KEY=...
SUPABASE_100_SERVICE_ROLE_KEY=...
# Supabase for chain 137 (Polygon)
SUPABASE_137_URL=https://...
SUPABASE_137_ANON_KEY=...
SUPABASE_137_SERVICE_ROLE_KEY=...
# Supabase for chain 42220 (Celo)
SUPABASE_42220_URL=https://...
SUPABASE_42220_ANON_KEY=...
SUPABASE_42220_SERVICE_ROLE_KEY=...
SERVER_42220_ACCOUNT_ADDRESS=
SERVER_42220_WALLET_PRIVATE_KEY=
# Supabase for chain 8453 (Base)
SUPABASE_8453_URL=https://...
SUPABASE_8453_ANON_KEY=...
SUPABASE_8453_SERVICE_ROLE_KEY=...
# ONRAMP
TRANSAK_API_KEY=...
74 changes: 37 additions & 37 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files
.env*
!.env.example

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files
!.env.example
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
config.bat
79 changes: 79 additions & 0 deletions app/(home)/_components/Top-sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
'use client'

import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarRail
} from '@/components/ui/sidebar';
import { Home } from 'lucide-react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import Image from 'next/image';
import { Button } from '@/components/ui/button';
import { PlusIcon } from 'lucide-react';

export default function Topsidebar({
account,
balance
}: {
account: string;
balance: number;
}) {

const pathname = usePathname();

const sidebar = [{
name: 'Communities',
url: `/`,
icon: Home
}];
return (
<>
<Sidebar collapsible="icon">
<SidebarContent>
<SidebarGroup>
<SidebarMenu className='mt-8'>
{sidebar.map((item) => (
<SidebarMenuItem key={item.name} >
<SidebarMenuButton asChild className={`${pathname === item.url ? 'bg-gray-200' : ''}`}>
<Link href={item.url}>
<item.icon />
<span>{item.name}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroup>
</SidebarContent>

<SidebarFooter>
<div className="flex justify-between items-center text-md px-2 py-2 gap-2 bg-sidebar-accent rounded-lg">
<Image
src="https://assets.citizenwallet.xyz/wallet-config/_images/ctzn.svg"
alt="CTZN"
width={28}
height={28}
/>
<p className="flex-1 px-4 py-2">{balance.toFixed(2)}</p>
<Button variant="default" size="sm"
onClick={() => {
window.open(`/onramp?account=${account}`, '_blank');
}}
>
<PlusIcon />
</Button>
</div>

</SidebarFooter>

<SidebarRail />
</Sidebar>
</>
)
}
118 changes: 59 additions & 59 deletions app/(home)/_components/alias-utils.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,59 @@
import { z } from 'zod';

export const sanitizeAlias = (alias: string): string => {
return alias
.toLowerCase()
.replace(/[^a-z0-9-]/g, '-')
.replace(/-+/g, '-')
.replace(/^-+|-+$/g, '')
.slice(0, 50);
};

export const isValidAlias = (alias: string): boolean => {
// Check if alias is not empty after sanitization
if (!alias || alias.length === 0) {
return false;
}

// Check if alias contains only lowercase letters, numbers, and hyphens
const validPattern = /^[a-z0-9-]+$/;
if (!validPattern.test(alias)) {
return false;
}

// Check if alias doesn't start or end with hyphen
if (alias.startsWith('-') || alias.endsWith('-')) {
return false;
}

// Check if alias doesn't have consecutive hyphens
if (alias.includes('--')) {
return false;
}

return true;
};

export const aliasSchema = z
.string({
required_error: 'Alias is required'
})
.min(1, {
message: 'Alias cannot be empty'
})
.max(50, {
message: 'Alias must be 50 characters or less'
})
.refine(
(val) => {
const sanitized = sanitizeAlias(val);
return sanitized === val;
},
{
message: 'Alias must contain only lowercase letters, numbers, and hyphens'
}
)
.refine((val) => isValidAlias(val), {
message:
'Alias must be a valid format (no leading/trailing hyphens, no consecutive hyphens)'
});
import { z } from 'zod';
export const sanitizeAlias = (alias: string): string => {
return alias
.toLowerCase()
.replace(/[^a-z0-9-]/g, '-')
.replace(/-+/g, '-')
.replace(/^-+|-+$/g, '')
.slice(0, 50);
};
export const isValidAlias = (alias: string): boolean => {
// Check if alias is not empty after sanitization
if (!alias || alias.length === 0) {
return false;
}
// Check if alias contains only lowercase letters, numbers, and hyphens
const validPattern = /^[a-z0-9-]+$/;
if (!validPattern.test(alias)) {
return false;
}
// Check if alias doesn't start or end with hyphen
if (alias.startsWith('-') || alias.endsWith('-')) {
return false;
}
// Check if alias doesn't have consecutive hyphens
if (alias.includes('--')) {
return false;
}
return true;
};
export const aliasSchema = z
.string({
required_error: 'Alias is required'
})
.min(1, {
message: 'Alias cannot be empty'
})
.max(50, {
message: 'Alias must be 50 characters or less'
})
.refine(
(val) => {
const sanitized = sanitizeAlias(val);
return sanitized === val;
},
{
message: 'Alias must contain only lowercase letters, numbers, and hyphens'
}
)
.refine((val) => isValidAlias(val), {
message:
'Alias must be a valid format (no leading/trailing hyphens, no consecutive hyphens)'
});
Loading