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
95 changes: 95 additions & 0 deletions src/app/api/Intents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import {
axiosDelete,
axiosGet,
axiosPost,
axiosPut,
} from '@/services/apiRequests'

import { AxiosResponse } from 'axios'
import { apiRoutes } from '@/config/apiRoutes'
import { getHeaderConfigs } from '@/config/GetHeaderConfigs'

interface IPagination {
page: number
itemPerPage: number
search?: string
sortBy?: string
sortingOrder?: string
}

export const getAllIntents = async (
ecosystemId: string,
options: IPagination,
): Promise<string | AxiosResponse> => {
const url = `${apiRoutes.intents.root}${apiRoutes.Ecosystem.root}/${ecosystemId}?pageSize=${options.itemPerPage}&pageNumber=${options.page}&search=${options.search}&sortBy=${options.sortingOrder}&sortField=${options.sortBy}`
const axiosPayload = {
url,
config: getHeaderConfigs(),
}

try {
return await axiosGet(axiosPayload)
} catch (error) {
const err = error as Error
return err?.message
}
}

export const createIntent = async (
ecosystemId: string,
payload: { name: string; description: string },
): Promise<string | AxiosResponse> => {
const url = `${apiRoutes.intents.root}${apiRoutes.Ecosystem.root}/${ecosystemId}`
const axiosPayload = {
url,
payload,
config: getHeaderConfigs(),
}

try {
return await axiosPost(axiosPayload)
} catch (error) {
const err = error as Error
return err?.message
}
}

export const updateIntent = async (
ecosystemId: string,
intentId: string,
data: { name: string; description: string },
): Promise<string | AxiosResponse> => {
const url = `${apiRoutes.intents.root}${apiRoutes.Ecosystem.root}/${ecosystemId}/${intentId}`

const axiosPayload = {
url,
payload: data,
config: getHeaderConfigs(),
}

try {
return await axiosPut(axiosPayload)
} catch (error) {
const err = error as Error
return err?.message
}
}

export const deleteIntent = async (
ecosystemId: string,
intentId: string,
): Promise<string | AxiosResponse> => {
const url = `${apiRoutes.intents.root}${apiRoutes.Ecosystem.root}/${ecosystemId}/${intentId}`

const axiosPayload = {
url,
config: getHeaderConfigs(),
}

try {
return await axiosDelete(axiosPayload)
} catch (error) {
const err = error as Error
return err?.message
}
}
2 changes: 1 addition & 1 deletion src/app/api/ecosystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export const acceptRejectMemberInvitation = async (
}

try {
return await axiosPost(axiosPayload)
return await axiosPut(axiosPayload)
} catch (error) {
const err = error as Error
return err?.message
Expand Down
10 changes: 10 additions & 0 deletions src/app/intents/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import IntentList from '@/features/intents/IntentList'
import React from 'react'

const page = (): React.JSX.Element => (
<div>
<IntentList />
</div>
)

export default page
3 changes: 3 additions & 0 deletions src/common/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export enum Features {
ISSUANCE = 'issuance',
VERIFICATION = 'verification',
CREATE_CERTIFICATE = 'create_certificate',
ECOSYSTEM = 'ecosystem'
}

export enum SchemaTypes {
Expand All @@ -65,6 +66,8 @@ export enum Roles {
ISSUER = 'issuer',
VERIFIER = 'verifier',
MEMBER = 'member',
ECOSYSTEM_LEAD = 'ecosystem lead',
ECOSYSTEM_MEMBER = 'ecosystem member'
}

export enum OrganizationRoles {
Expand Down
6 changes: 6 additions & 0 deletions src/components/RoleViewButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ const RoleViewButton = ({
roles.includes(Roles.VERIFIER)
)

case Features.ECOSYSTEM:
return (

roles.includes(Roles.ECOSYSTEM_LEAD)
)

default:
return roles.includes(Roles.OWNER) || roles.includes(Roles.ADMIN)
}
Expand Down
4 changes: 4 additions & 0 deletions src/config/apiRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export const apiRoutes = {
deleteSession: '/auth/sessionId:/sessions',
},

intents: {
root:'/intent'
},

users: {
userProfile: '/users/profile',
checkUser: '/users/',
Expand Down
1 change: 1 addition & 0 deletions src/features/components/SessionManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const preventRedirectOnPaths = [
'/wallet-setup',
'/create-did',
'/x509-certificate',
'/intents',
'/did-details',
'/organizations',
'/users',
Expand Down
7 changes: 7 additions & 0 deletions src/features/ecosystems/components/Manage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import { useRouter, useSearchParams } from 'next/navigation'
import { ArrowLeft } from 'lucide-react'
import { Button } from '@/components/ui/button'
import Create from './Create'
import IntentList from '@/features/intents/IntentList'
import { Invitaitons } from './Invitations'
import { Members } from './Members'
import { useAppSelector } from '@/lib/hooks'

const Manage = (): JSX.Element => {
const [activeTab, setActiveTab] = useState('Invitations')
const ecosystemName = useAppSelector((state) => state.ecosystem.name)
const ecosystemId = useAppSelector((state) => state.ecosystem.id)
const searchParams = useSearchParams()
const showCreateForm = searchParams.get('createNew') === 'true'
const router = useRouter()
Expand Down Expand Up @@ -57,6 +59,7 @@ const Manage = (): JSX.Element => {
<TabsTrigger value="Members" className="relative">
Members
</TabsTrigger>
<TabsTrigger value="Intents">Intents</TabsTrigger>
<TabsTrigger value="Create" disabled={!showCreateForm}>
Create
</TabsTrigger>
Expand All @@ -67,6 +70,10 @@ const Manage = (): JSX.Element => {
<TabsContent value="Members">
<Members />
</TabsContent>
<TabsContent value="Intents" className="mt-2">
<IntentList ecosystemId={ecosystemId} />
</TabsContent>

<TabsContent
value="Create"
className="mt-2 space-y-4 rounded-md border p-4"
Expand Down
126 changes: 126 additions & 0 deletions src/features/intents/IntentFormDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
'use client'

import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog'

import { AlertComponent } from '@/components/AlertComponent'
import { JSX } from 'react'

interface IntentFormDialogProps {
open: boolean
setOpen: (open: boolean) => void
isEdit: boolean
intentName: string
intentDesc: string
setIntentName: (value: string) => void
setIntentDesc: (value: string) => void
handleSubmit: () => void
creating: boolean
success: string | null
failure: string | null
setSuccess: (val: string | null) => void
setFailure: (val: string | null) => void
resetFormState: () => void
}

const IntentFormDialog = ({
open,
setOpen,
isEdit,
intentName,
intentDesc,
setIntentName,
setIntentDesc,
handleSubmit,
creating,
success,
failure,
setSuccess,
setFailure,
resetFormState,
}: IntentFormDialogProps): JSX.Element => (
<Dialog
open={open}
onOpenChange={(value) => {
setOpen(value)

if (!value) {
resetFormState()
}
}}
>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
{success && (
<AlertComponent
message={success}
type="success"
onAlertClose={() => setSuccess(null)}
/>
)}

{failure && (
<AlertComponent
message={failure}
type="failure"
onAlertClose={() => setFailure(null)}
/>
)}

<DialogTitle>{isEdit ? 'Update Intent' : 'Create Intent'}</DialogTitle>
</DialogHeader>

<div className="space-y-4 pt-2">
<div className="space-y-1">
<label className="text-sm font-medium">Intent Name *</label>
<input
type="text"
value={intentName}
onChange={(e) => setIntentName(e.target.value)}
placeholder="Enter intent name"
className="focus:ring-primary w-full rounded-md border px-3 py-2 text-sm outline-none focus:ring-2"
/>
</div>

<div className="space-y-1">
<label className="text-sm font-medium">Description</label>
<textarea
value={intentDesc}
onChange={(e) => setIntentDesc(e.target.value)}
placeholder="Enter description"
className="focus:ring-primary w-full rounded-md border px-3 py-2 text-sm outline-none focus:ring-2"
rows={3}
/>
</div>

<div className="flex justify-end gap-2 pt-2">
<button
type="button"
onClick={() => setOpen(false)}
className="rounded-md border px-4 py-2 text-sm"
>
Cancel
</button>

<button
type="button"
onClick={handleSubmit}
disabled={creating || !intentName.trim()}
className="bg-primary flex items-center gap-2 rounded-md px-4 py-2 text-sm text-white"
>
{creating && (
<span className="h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" />
)}
{isEdit ? 'Update' : 'Create'}
</button>
</div>
</div>
</DialogContent>
</Dialog>
)

export default IntentFormDialog
Loading