Skip to content
Draft
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
7 changes: 4 additions & 3 deletions src/pages/ownership.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { GLOBAL_CONSTANTS } from '@src/config-global.ts';
import { OgMetaTags } from '@src/components/og-meta-tags.tsx';
import Header from '@src/layouts/dashboard/header.tsx';
import HeaderContent from '@src/layouts/dashboard/header-content.tsx';
import { OwnershipView } from '@src/sections/ownership/index';
import { OwnershipView } from '@src/sections/ownership';
import { useSelector } from 'react-redux';
import {WithAuth} from "@src/components/should-login/withAuth.tsx"

// ----------------------------------------------------------------------

Expand All @@ -31,9 +32,9 @@ export default function FileManagerPage() {
{canViewSection(sessionData) ? (
<>
<Header>
<HeaderContent title="Ownership" />
<HeaderContent title="Finance" />
</Header>
<OwnershipView />
<WithAuth component={OwnershipView} description={'Login to view your assets.'} icon={'iconoir:stats-report'} header={'Ownership Dashboard'} />
</>
) : (
<BlankView>
Expand Down
4 changes: 2 additions & 2 deletions src/sections/marketing/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ export interface CampaignType {
expiration: number;
}

export interface CampaignTableRowType extends CampaignType {}
export type CampaignTableRowType = CampaignType

export interface CampaignTableRowProps {
row: CampaignTableRowType;
selected: boolean;
}

export interface CampaignModalContentProps {
onConfirm?: () => void;
onClose: () => void;
onConfirm: () => void;
}

export interface CampaignConfiguredIndicatorStateProps {
Expand Down
27 changes: 27 additions & 0 deletions src/sections/ownership/CONSTANTS.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { COLORS } from '@src/sections/finance/CONSTANTS.tsx';

export const OWNERSHIP_TABLE_HEAD = [
{ id: 'name', label: 'Publication', minWidth: 300 },
{ id: 'limit', label: 'Policies', minWidth: 100},
{ id: 'budget', label: 'Restrictions', minWidth: 100},
{ id: 'status', label: 'Status', minWidth: 100 },
];

export const LBL_STATUS_COLORS = {
active: COLORS.success,
deactivated: COLORS.warning,
};

export const LBL_TYPES_TEXTS = [
{id: 1,name: "Subscription"},
{id: 2,name: "Rent"},
{id: 3,name: "Buy",}
];

export const LBL_REGIONS_TEXTS = [
{id: 1,name: "US"},
{id: 2,name: "EU"},
{id: 3,name: "ASIA"},
{id: 4,name: "LATAM"},
{id: 5,name: "AFRICA"},
]
53 changes: 53 additions & 0 deletions src/sections/ownership/components/ownership-create.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// MUI IMPORTS
import Button from '@mui/material/Button';

// LOCAL IMPORTS
import Iconify from '@src/components/iconify';
import OwnershipModal from '@src/components/modal';
import { useBoolean } from '@src/hooks/use-boolean';
import { FC } from 'react';
import { CampaignCreateProps } from '@src/sections/marketing/types.ts';
import {OwnershipModalContent} from "@src/sections/ownership/components/ownership-modal-content.tsx"

// ----------------------------------------------------------------------

const OwnershipCreate: FC<CampaignCreateProps> = ({ onSuccess }) => {
const ownershipConfirmPublish = useBoolean();

const handleClose = () => {
ownershipConfirmPublish.onFalse?.();
};

const handleClick = () => {
ownershipConfirmPublish.onTrue?.();
};

const handleConfirm = () => {
onSuccess?.();
ownershipConfirmPublish.onFalse();
};

return (
<>
<Button
onClick={handleClick}
startIcon={<Iconify icon={'typcn:plus'} />}
variant="contained"
sx={{
color: 'white',
background: '#8E33FF',
}}
>
Register
</Button>
<OwnershipModal
title="Register an asset"
open={ownershipConfirmPublish.value}
onClose={handleClose}
renderContent={<OwnershipModalContent onConfirm={handleConfirm} onClose={handleClose} />}
/>
</>
);
};

export {OwnershipCreate};
138 changes: 138 additions & 0 deletions src/sections/ownership/components/ownership-modal-content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import LoadingButton from "@mui/lab/LoadingButton";
import NeonPaper from '@src/sections/publication/components/neon-paper-container.tsx';
import { FC, useState } from 'react';
import {
Button,
DialogActions,
Divider,

Box, Typography, TextField, Stack,
} from '@mui/material'
import {notifyError, notifyInfo, notifySuccess} from '@notifications/internal-notifications.ts'
import { SUCCESS } from '@notifications/success.ts';
import { CampaignModalContentProps } from '@src/sections/marketing/types.ts';
import Iconify from "@src/components/iconify"
import {INFO} from "@notifications/info.ts"
import {ERRORS} from "@notifications/errors.ts"
import {replacePrefix} from "@src/utils/wallet.ts"
import {useRegisterAsset} from "@src/hooks/protocol/use-register-asset.ts"
import {useSubmitAssetToLens} from "@src/hooks/use-submit-assets-to-lens.ts"
import {useGetAssetOwner} from "@src/hooks/protocol/use-get-asset-owner.ts"
// ----------------------------------------------------------------------

const OwnershipModalContent: FC<CampaignModalContentProps> = ({ onClose, onConfirm }) => {
const [hashes, setHashes] = useState<string>('');
const { registerAsset } = useRegisterAsset();
const { submitAssetToLens } = useSubmitAssetToLens();
const { fetchOwnerAddress } = useGetAssetOwner();
const [isProcessing, setIsProcessing] = useState(false);
const [progress, setProgress] = useState(0);
const hashesArray = hashes.split(',')
.map(h => h.trim())
.filter(Boolean);

const RainbowEffect = isProcessing ? NeonPaper : Box;

// Validate fields, calculate expiration in seconds, and call the create function from the hook
const handleRegister = async () => {
if (!hashes) return;

setProgress(1);
setIsProcessing(true);

try {
for (const [index, hash] of hashesArray.entries()) {
try {
// 1. Report progress
notifyInfo(INFO.REGISTER_OWNERSHIP_PROGRESS, {
index: index + 1,
total: hashesArray.length,
options: { autoHideDuration: 3000 }
}, '', { autoHideDuration: 3000 });
setProgress(index + 1);

const isTaken = await fetchOwnerAddress(hash);

if (isTaken) {
notifyError(ERRORS.ASSET_ALREADY_REGISTERED_ERROR);
continue;
}

if (!isTaken) {
// 2. Register ownership (if it fails, it does not continue)
await registerAsset(hash);
}

// 3. Upload to Lens only if registration was successful
await submitAssetToLens(replacePrefix(hash));
notifySuccess(SUCCESS.OWNERSHIP_REGISTERED_SUCCESSFULLY, { count: index + 1 });
} catch (error) {
notifyError(ERRORS.ASSET_OWNERSHIP_REGISTER_ERROR, { hash: `${index + 1}/${hashesArray.length}` });
continue; // Continue with the next hash
}
}
} catch (error) {
notifyError(ERRORS.ASSET_OWNERSHIP_REGISTER_ERROR);
} finally {
setIsProcessing(false);
onClose();
}
};

return (
<>
<Divider sx={{ padding: '0.3rem 0', mb: 2, borderStyle: 'dashed' }} />
<Stack direction="column" >
<Box sx={{ px: 3 }}>
<Typography variant="body1">
Enter the hash(es) of the content you want to register
</Typography>
<Typography variant="body2" sx={{ mb: 2, opacity: 0.7 }}>
You can enter multiple hashes separated by commas.
</Typography>

<TextField
sx={{ mt: 1, mb: 2 }}
fullWidth
autoFocus
label="Content Hash(es)"
type="text"
value={hashes}
onChange={(e) => setHashes(e.target.value)}
placeholder="e.g., hash1,hash2,hash3"
disabled={isProcessing}
/>
</Box>
</Stack>
<Divider sx={{ padding: '0.3rem 0', mt: 2, borderStyle: 'dashed' }} />

<DialogActions sx={{ px: 2, display: 'flex', justifyContent: 'flex-end', gap: 1 }}>
<Button variant="outlined" onClick={onClose} disabled={isProcessing}>
Cancel
</Button>
<RainbowEffect
{...(isProcessing && {
borderRadius: '10px',
animationSpeed: '3s',
padding: '0',
width: 'auto',
})}
>
<LoadingButton
variant="contained"
sx={{ backgroundColor: 'white', color: 'black' }}
onClick={handleRegister}
disabled={!hashes || isProcessing}
loading={isProcessing}
loadingPosition="start"
startIcon={<Iconify icon="material-symbols:publish" />}
>
Confirm
</LoadingButton>
</RainbowEffect>
</DialogActions>
</>
);
};

export {OwnershipModalContent};
Loading
Loading