From 36a1ad3fe729d7915b769d1206ad80b5c2f2c19f Mon Sep 17 00:00:00 2001 From: ryangtanaka Date: Thu, 19 Dec 2024 16:42:37 -0800 Subject: [PATCH 01/13] first draft of waveform image generator --- package-lock.json | 10 ++ package.json | 1 + .../form/AudioCoverMetadataOverlay.tsx | 94 ++++++++++ src/components/form/FormFields.jsx | 170 ++++++++++++++++-- src/components/form/MintForm.jsx | 5 +- src/components/form/index.module.scss | 12 +- src/components/upload/index.module.scss | 1 + src/utils/mint.ts | 19 ++ 8 files changed, 292 insertions(+), 20 deletions(-) create mode 100644 src/components/form/AudioCoverMetadataOverlay.tsx diff --git a/package-lock.json b/package-lock.json index f73254594..a4e699deb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "markdown-to-jsx": "^7.1.9", "mime-types": "^2.1.35", "react": "^18.2.0", + "react-audio-visualize": "^1.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.43.1", "react-infinite-scroller": "^1.2.6", @@ -18600,6 +18601,15 @@ "node": ">=0.10.0" } }, + "node_modules/react-audio-visualize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/react-audio-visualize/-/react-audio-visualize-1.2.0.tgz", + "integrity": "sha512-rfO5nmT0fp23gjU0y2WQT6+ZOq2ZsuPTMphchwX1PCz1Di4oaIr6x7JZII8MLrbHdG7UB0OHfGONTIsWdh67kQ==", + "peerDependencies": { + "react": ">=16.2.0", + "react-dom": ">=16.2.0" + } + }, "node_modules/react-colorful": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", diff --git a/package.json b/package.json index f6178185a..7f36c78eb 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "markdown-to-jsx": "^7.1.9", "mime-types": "^2.1.35", "react": "^18.2.0", + "react-audio-visualize": "^1.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.43.1", "react-infinite-scroller": "^1.2.6", diff --git a/src/components/form/AudioCoverMetadataOverlay.tsx b/src/components/form/AudioCoverMetadataOverlay.tsx new file mode 100644 index 000000000..52562de2d --- /dev/null +++ b/src/components/form/AudioCoverMetadataOverlay.tsx @@ -0,0 +1,94 @@ +import React, { useEffect, useRef } from 'react'; + +export const combineVisualizerWithMetadata = async ( + visualizerRef: HTMLDivElement, + fileValue: { + artifact?: { + name?: string; + size?: number; + mimeType?: string; + }; + } +): Promise => { + return new Promise((resolve, reject) => { + try { + // Create a new canvas for the final image + const finalCanvas = document.createElement('canvas'); + finalCanvas.width = 618; // Match the AudioVisualizer dimensions + finalCanvas.height = 382; + + const ctx = finalCanvas.getContext('2d'); + if (!ctx) throw new Error('Could not get canvas context'); + + // Fill with black background + ctx.fillStyle = 'black'; + ctx.fillRect(0, 0, finalCanvas.width, finalCanvas.height); + + // Get both canvas elements + const visualizerCanvas = visualizerRef.querySelector('canvas'); + const metadataCanvas = visualizerRef.querySelector('canvas:last-child'); + + if (!visualizerCanvas || !metadataCanvas) { + throw new Error('Could not find canvas elements'); + } + + // First draw the visualizer + ctx.drawImage(visualizerCanvas, 0, 0); + + // Then draw the metadata canvas on top + ctx.drawImage(metadataCanvas, 0, 0); + + finalCanvas.toBlob((blob) => { + if (blob) resolve(blob); + else reject(new Error('Failed to create blob')); + }, 'image/png'); + } catch (error) { + reject(error); + } + }); +}; + +interface MetadataOverlayProps { + title: string; + artist: string; + style?: React.CSSProperties; +} + +const MetadataOverlay: React.FC = ({ + title, + artist, + style +}) => { + const canvasRef = useRef(null); + + useEffect(() => { + const canvas = canvasRef.current; + if (!canvas) return; + + const ctx = canvas.getContext('2d'); + if (!ctx) return; + + ctx.clearRect(0, 0, canvas.width, canvas.height); + + ctx.fillStyle = 'white'; + ctx.font = '16px monospace'; + ctx.globalAlpha = 0.8; + + // Draw metadata + ctx.fillText(`Title: ${title}`, 20, 30); + ctx.fillText(`Artist: ${artist}`, 20, 55); + ctx.fillText(`Date: ${new Date().toLocaleDateString()}`, 20, 80); + + }, [title, artist]); + + return ( + + ); +}; + +export default MetadataOverlay; \ No newline at end of file diff --git a/src/components/form/FormFields.jsx b/src/components/form/FormFields.jsx index 6932fcc63..2e4910b66 100644 --- a/src/components/form/FormFields.jsx +++ b/src/components/form/FormFields.jsx @@ -2,15 +2,23 @@ import { Checkbox, Input, Textarea } from '@atoms/input' import { Line } from '@atoms/line' import Select from '@atoms/select/Base' import styles from '@style' -import { memo } from 'react' +import { memo, useState, useRef } from 'react' import { Upload } from '@components/upload/index' +import { AudioVisualizer } from 'react-audio-visualize' import { ALLOWED_FILETYPES_LABEL, ALLOWED_COVER_FILETYPES_LABEL, } from '@constants' -import { Controller } from 'react-hook-form' +import { Controller, useFormContext } from 'react-hook-form' import classNames from 'classnames' import CustomCopyrightForm from './CustomCopyrightForm' +import { processAudioForVisualizer } from '@utils/mint' +import { Button } from '@atoms/button' +import MetadataOverlay, { + combineVisualizerWithMetadata, +} from './AudioCoverMetadataOverlay' +import { useUserStore } from '@context/userStore' +import { shallow } from 'zustand/shallow' const FieldError = memo(({ error, text }) => { const classes = classNames({ @@ -25,6 +33,25 @@ const FieldError = memo(({ error, text }) => { */ export const FormFields = ({ value, field, error, register, control }) => { const name = field.name + const { watch } = useFormContext() + const [address, userInfo] = useUserStore( + (st) => [st.address, st.userInfo], + shallow + ) + const [showVisualizer, setShowVisualizer] = useState(false) + const visualizerRef = useRef(null) + const AUDIO_MIME_TYPES = [ + 'audio/mpeg', + 'audio/wav', + 'audio/flac', + 'audio/x-flac', + ] + const getArtistText = (userInfo, address) => { + if (userInfo?.name) { + return `${userInfo.name} (${address})` + } + return address + } switch (field.type) { case 'text': @@ -138,20 +165,131 @@ export const FormFields = ({ value, field, error, register, control }) => { defaultValue={field.defaultValue} name={name} rules={field.rules} - render={({ field: { onChange, value, name, ref } }) => ( - - {error && } - - )} + render={({ field: { onChange, value, name, ref } }) => { + const fileValue = watch(value) + + const isAudioMimeType = + fileValue && + AUDIO_MIME_TYPES.includes(fileValue.artifact?.mimeType) + const audioBlob = processAudioForVisualizer( + fileValue?.artifact.reader + ) + + const containerStyle = { + position: 'relative', + width: '100%', + maxWidth: '618px', + height: '382px', + maxHeight: '382px', + backgroundColor: 'black', + overflow: 'hidden', + } + + const visualizerContainerStyle = { + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%', + } + + const handleSaveImage = async () => { + if (!visualizerRef.current) return + + try { + const finalBlob = await combineVisualizerWithMetadata( + visualizerRef.current, + fileValue + ) + + const url = URL.createObjectURL(finalBlob) + const a = document.createElement('a') + a.href = url + a.download = `${fileValue.artifact?.name || 'audio'}_cover.png` + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + URL.revokeObjectURL(url) + + const newFile = new File( + [finalBlob], + `${fileValue.artifact?.name || 'audio'}_cover.png`, + { type: 'image/png' } + ) + onChange({ file: newFile }) + } catch (error) { + console.error('Failed to save image:', error) + } + } + + return ( + <> + {isAudioMimeType && !showVisualizer && ( + + )} + + {isAudioMimeType && showVisualizer && ( +
+

Generated Image (Save and Upload Manually)

+
+
+ + +
+
+ +
+ )} + + + {error && } + + + ) + }} /> ) diff --git a/src/components/form/MintForm.jsx b/src/components/form/MintForm.jsx index 4660ff32a..f66b7d357 100644 --- a/src/components/form/MintForm.jsx +++ b/src/components/form/MintForm.jsx @@ -17,7 +17,6 @@ import { generateTypedArtCoverImage, } from '@utils/mint' import { AUTO_GENERATE_COVER_MIMETYPES } from '@constants' -import { Midi } from '@tonejs/midi' import { processMidiCover } from '@utils/midi' export default function MintForm() { @@ -102,8 +101,8 @@ export default function MintForm() { } else if (data.typedinput) { data = await processTypedInput(data) } else if ( - data.artifact.mimeType == 'audio/midi' || - data.artifact.mimeType == 'audio/mid' + data.artifact.mimeType === 'audio/midi' || + data.artifact.mimeType === 'audio/mid' ) { // generate midi cover and set as data.object data = await processMidiCover(data) diff --git a/src/components/form/index.module.scss b/src/components/form/index.module.scss index 50ff1203a..6bfa8ee80 100644 --- a/src/components/form/index.module.scss +++ b/src/components/form/index.module.scss @@ -8,7 +8,7 @@ } .field { - margin: 0; + margin: 0.382em 0 0 0; } .typed_field { @@ -46,3 +46,13 @@ .modalInfoIcon:hover { color: var(--highlight-color); } + +.visualizer-image-download-button { + border: 1px solid white !important; + padding: 5px; + margin: 5px; +} + +.visualizer-image-download-button:hover { + text-decoration: underline; +} diff --git a/src/components/upload/index.module.scss b/src/components/upload/index.module.scss index 0d55e7ad0..2e3b0a978 100644 --- a/src/components/upload/index.module.scss +++ b/src/components/upload/index.module.scss @@ -1,4 +1,5 @@ .container { + margin-top: 10px; margin-bottom: 10px; label, diff --git a/src/utils/mint.ts b/src/utils/mint.ts index fd6e566d0..383f37f62 100644 --- a/src/utils/mint.ts +++ b/src/utils/mint.ts @@ -357,3 +357,22 @@ export const convertFileToFileForm = async ( format, } } + +/** + * Processes an audio data URI into a blob for AudioVisualizer + * @param {string} reader - The data URI from the artifact reader + * @returns {Blob} The processed audio blob + */ + +export const processAudioForVisualizer = (reader: string) => { + const rawBase64 = reader.split(',')[1] || reader; + const byteString = atob(rawBase64); + const arrayBuffer = new ArrayBuffer(byteString.length); + const uint8Array = new Uint8Array(arrayBuffer); + + for (let i = 0; i < byteString.length; i++) { + uint8Array[i] = byteString.charCodeAt(i); + } + + return new Blob([arrayBuffer], { type: 'audio/mpeg' }); +}; \ No newline at end of file From ddfd454c3e1f34efda3981559750b15aa287227f Mon Sep 17 00:00:00 2001 From: ryangtanaka Date: Fri, 20 Dec 2024 11:22:29 -0800 Subject: [PATCH 02/13] metadata tweaks and fixes --- src/components/form/AudioCoverMetadataOverlay.tsx | 15 +++++++++------ src/components/form/FormFields.jsx | 2 ++ src/constants.ts | 3 +-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/components/form/AudioCoverMetadataOverlay.tsx b/src/components/form/AudioCoverMetadataOverlay.tsx index 52562de2d..44a4ca6ea 100644 --- a/src/components/form/AudioCoverMetadataOverlay.tsx +++ b/src/components/form/AudioCoverMetadataOverlay.tsx @@ -25,8 +25,8 @@ export const combineVisualizerWithMetadata = async ( ctx.fillRect(0, 0, finalCanvas.width, finalCanvas.height); // Get both canvas elements - const visualizerCanvas = visualizerRef.querySelector('canvas'); - const metadataCanvas = visualizerRef.querySelector('canvas:last-child'); + const visualizerCanvas = visualizerRef.querySelector('canvas') as HTMLCanvasElement | null; + const metadataCanvas = visualizerRef.querySelector('canvas:last-child') as HTMLCanvasElement | null; if (!visualizerCanvas || !metadataCanvas) { throw new Error('Could not find canvas elements'); @@ -51,12 +51,14 @@ export const combineVisualizerWithMetadata = async ( interface MetadataOverlayProps { title: string; artist: string; + mimeType: string; style?: React.CSSProperties; } const MetadataOverlay: React.FC = ({ title, artist, + mimeType, style }) => { const canvasRef = useRef(null); @@ -75,11 +77,12 @@ const MetadataOverlay: React.FC = ({ ctx.globalAlpha = 0.8; // Draw metadata - ctx.fillText(`Title: ${title}`, 20, 30); - ctx.fillText(`Artist: ${artist}`, 20, 55); - ctx.fillText(`Date: ${new Date().toLocaleDateString()}`, 20, 80); + ctx.fillText(`Title: ${title}`, 20, 25); + ctx.fillText(`Artist: ${artist}`, 20, 45); + ctx.fillText(`Date: ${new Date().toLocaleDateString()}`, 20, 65); + ctx.fillText(`Type: ${mimeType}`, 20, 85); - }, [title, artist]); + }, [title, artist, mimeType]); return ( { 'audio/wav', 'audio/flac', 'audio/x-flac', + 'audio/ogg', ] const getArtistText = (userInfo, address) => { if (userInfo?.name) { @@ -255,6 +256,7 @@ export const FormFields = ({ value, field, error, register, control }) => { Date: Fri, 20 Dec 2024 11:40:21 -0800 Subject: [PATCH 03/13] metadata styling (and added teia's contract) --- src/components/form/AudioCoverMetadataOverlay.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/form/AudioCoverMetadataOverlay.tsx b/src/components/form/AudioCoverMetadataOverlay.tsx index 44a4ca6ea..05f97a8e0 100644 --- a/src/components/form/AudioCoverMetadataOverlay.tsx +++ b/src/components/form/AudioCoverMetadataOverlay.tsx @@ -1,3 +1,4 @@ +import { HEN_CONTRACT_FA2 } from '@constants'; import React, { useEffect, useRef } from 'react'; export const combineVisualizerWithMetadata = async ( @@ -77,10 +78,11 @@ const MetadataOverlay: React.FC = ({ ctx.globalAlpha = 0.8; // Draw metadata - ctx.fillText(`Title: ${title}`, 20, 25); - ctx.fillText(`Artist: ${artist}`, 20, 45); - ctx.fillText(`Date: ${new Date().toLocaleDateString()}`, 20, 65); - ctx.fillText(`Type: ${mimeType}`, 20, 85); + ctx.fillText(`Title: ${title}`, 15, 25); + ctx.fillText(`Wallet: ${artist}`, 15, 45); + ctx.fillText(`${new Date().toISOString()}`, 15, 65); + ctx.fillText(`${mimeType}`, 15, 85); + ctx.fillText(`Mint Contract: ${HEN_CONTRACT_FA2} (HEN/TEIA)`, 15, 370); }, [title, artist, mimeType]); From d30eee5911a9c350604fa0777ef6e425b90e2d2a Mon Sep 17 00:00:00 2001 From: ryangtanaka Date: Sat, 4 Jan 2025 15:16:44 -0800 Subject: [PATCH 04/13] fixed ogg error and rerendering lag --- src/components/form/FormFields.jsx | 18 ++++++--- src/components/media-types/index.tsx | 1 + src/components/media-types/unknown/index.jsx | 39 +++++++++++++++++--- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/components/form/FormFields.jsx b/src/components/form/FormFields.jsx index 3f8052a38..8957ba912 100644 --- a/src/components/form/FormFields.jsx +++ b/src/components/form/FormFields.jsx @@ -39,6 +39,7 @@ export const FormFields = ({ value, field, error, register, control }) => { shallow ) const [showVisualizer, setShowVisualizer] = useState(false) + const [audioBlob, setAudioBlob] = useState(null) const visualizerRef = useRef(null) const AUDIO_MIME_TYPES = [ 'audio/mpeg', @@ -168,13 +169,20 @@ export const FormFields = ({ value, field, error, register, control }) => { rules={field.rules} render={({ field: { onChange, value, name, ref } }) => { const fileValue = watch(value) - const isAudioMimeType = fileValue && AUDIO_MIME_TYPES.includes(fileValue.artifact?.mimeType) - const audioBlob = processAudioForVisualizer( - fileValue?.artifact.reader - ) + + const handleShowVisualizer = () => { + if (!showVisualizer && fileValue?.artifact?.reader) { + const blob = processAudioForVisualizer( + fileValue.artifact.reader + ) + // Store the processed blob on the fileValue object itself + setAudioBlob(blob) + } + setShowVisualizer(true) + } const containerStyle = { position: 'relative', @@ -228,7 +236,7 @@ export const FormFields = ({ value, field, error, register, control }) => { {isAudioMimeType && !showVisualizer && ( diff --git a/src/components/media-types/index.tsx b/src/components/media-types/index.tsx index 98858e099..6b6ad03b7 100644 --- a/src/components/media-types/index.tsx +++ b/src/components/media-types/index.tsx @@ -152,6 +152,7 @@ export const RenderMediaType = ({ ) /* AUDIO */ case MIMETYPE.MP3: + case MIMETYPE.OGG: case MIMETYPE.OGA: case MIMETYPE.FLAC: case MIMETYPE.WAV: diff --git a/src/components/media-types/unknown/index.jsx b/src/components/media-types/unknown/index.jsx index 076304d20..b8f19a0ed 100644 --- a/src/components/media-types/unknown/index.jsx +++ b/src/components/media-types/unknown/index.jsx @@ -1,12 +1,39 @@ -import styles from '@style' +import { useEffect, useState } from 'react' export const UnknownComponent = ({ mimeType }) => { - /* const [queue, updateQueue] = useState() - updateQueue(await axios.post(import.meta.env.VITE_GRAPHQL_STATUS).then(res => res.data)) - */ + const [processingState, setProcessingState] = useState('checking') + + useEffect(() => { + // If we have a mimeType that's known (like PNG), but we're still hitting this component, + // it likely means we're in a metadata processing state + const isKnownMimeType = mimeType?.toLowerCase().includes('png') + + if (isKnownMimeType) { + setProcessingState('processing') + } else { + setProcessingState('unknown') + } + }, [mimeType]) + return ( -
-
Metadata on queue
+
+
+ {processingState === 'processing' ? ( +
+

Metadata processing...

+

+ Please wait while we process your file +

+
+ ) : ( +
+

Unknown file type: {mimeType}

+

+ This file type is not supported +

+
+ )} +
) } From 4f91d69efe4061211cc5477a83eab3fb8e0a7567 Mon Sep 17 00:00:00 2001 From: ryangtanaka Date: Sun, 5 Jan 2025 20:26:15 -0800 Subject: [PATCH 05/13] mint form persist input fix and UI updates --- src/atoms/modal/index.module.scss | 1 + src/components/form/CustomCopyrightForm.jsx | 15 ++++++++++----- src/components/form/Form.jsx | 16 ++++++++++++++-- src/components/form/FormFields.jsx | 11 ++++++++++- src/components/form/copyrightmodaltext.ts | 2 +- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/atoms/modal/index.module.scss b/src/atoms/modal/index.module.scss index a5e202c27..37111798f 100644 --- a/src/atoms/modal/index.module.scss +++ b/src/atoms/modal/index.module.scss @@ -15,6 +15,7 @@ } .modalContent { + position: absolute; top: 0; background-color: var(--background-color); padding: 20px; diff --git a/src/components/form/CustomCopyrightForm.jsx b/src/components/form/CustomCopyrightForm.jsx index 924df10a0..8f6b92c65 100644 --- a/src/components/form/CustomCopyrightForm.jsx +++ b/src/components/form/CustomCopyrightForm.jsx @@ -19,7 +19,7 @@ const initialClauses = { exclusiveRights: 'none', // Options are 'none', 'majority', 'superMajority' retainCreatorRights: true, // When exclusive rights conditions are met, does the Creator retain their rights to their own work? releasePublicDomain: false, - requireAttribution: false, + requireAttribution: true, rightsAreTransferable: true, expirationDate: '', expirationDateExists: false, @@ -165,10 +165,12 @@ export const ClausesDescriptions = ({ clauses }) => { ) } -function CustomCopyrightForm({ onChange, value }) { +function CustomCopyrightForm({ onChange, value, defaultValue }) { const { watch } = useFormContext() const { license, minterName, address } = useOutletContext() - const [clauses, setClauses] = useState(initialClauses) + const [clauses, setClauses] = useState( + defaultValue?.clauses || initialClauses + ) const [generatedDocument, setGeneratedDocument] = useState( 'No Permissions Chosen' ) @@ -598,7 +600,8 @@ Unless stated otherwise (in this Agreement itself), this Agreement remains effec @@ -619,8 +622,9 @@ Unless stated otherwise (in this Agreement itself), this Agreement remains effec

{clauseLabels.expirationDate}

handleChange(e, 'expirationDate')} + defaultValue={defaultValue?.clauses?.expirationDate} className={styles.field} />
@@ -634,6 +638,7 @@ Unless stated otherwise (in this Agreement itself), this Agreement remains effec value={clauses?.addendum || ''} onChange={handleInputChange} placeholder="Add additional notes, clauses, restrictions, scopes, etc." + defaultValue={defaultValue?.clauses?.addendum} className={styles.field} /> diff --git a/src/components/form/Form.jsx b/src/components/form/Form.jsx index b447d8be7..7ebfba6fa 100644 --- a/src/components/form/Form.jsx +++ b/src/components/form/Form.jsx @@ -1,8 +1,9 @@ import Button from '@atoms/button/Button' import { get } from 'lodash' -import { memo } from 'react' +import { memo, useEffect } from 'react' import { useFormContext } from 'react-hook-form' import { FormFields } from './FormFields' +import { useMintStore } from '@context/mintStore' function Form({ fields, defaultValues, children, onSubmit, onReset }) { const { @@ -14,6 +15,14 @@ function Form({ fields, defaultValues, children, onSubmit, onReset }) { formState: { errors }, } = useFormContext() + // Watch all form values and update mintStore + const formValues = watch() + useEffect(() => { + if (Object.keys(formValues).length > 0) { + useMintStore.setState(formValues) + } + }, [formValues]) + return (
{fields.map((f) => { @@ -24,7 +33,10 @@ function Form({ fields, defaultValues, children, onSubmit, onReset }) { register={register} value={value} control={control} - field={f} + field={{ + ...f, + defaultValue: defaultValues?.[f.name], + }} error={get(errors, f.name)} /> ) diff --git a/src/components/form/FormFields.jsx b/src/components/form/FormFields.jsx index 8957ba912..592e87e3a 100644 --- a/src/components/form/FormFields.jsx +++ b/src/components/form/FormFields.jsx @@ -64,6 +64,7 @@ export const FormFields = ({ value, field, error, register, control }) => { name={name} type={field.type} label={field.label} + defaultValue={field.defaultValue} placeholder={field.placeholder} {...register(name, field.rules)} > @@ -77,6 +78,7 @@ export const FormFields = ({ value, field, error, register, control }) => { className={styles.field} label={field.label} placeholder={field.placeholder} + defaultValue={field.defaultValue} {...register(name, field.rules)} > @@ -89,6 +91,7 @@ export const FormFields = ({ value, field, error, register, control }) => { className={styles.typed_field} label={field.label} placeholder={field.placeholder} + defaultValue={field.defaultValue} {...register(name, field.rules)} > @@ -112,6 +115,7 @@ export const FormFields = ({ value, field, error, register, control }) => { search={field.type === 'select-search'} label={field.label} placeholder={field.placeholder} + defaultValue={field.defaultValue} onChange={onChange} /> )} @@ -129,6 +133,7 @@ export const FormFields = ({ value, field, error, register, control }) => { ref={ref} className={styles.field} label={field.label} + defaultValue={field.defaultValue} checked={value} onCheck={(v) => onChange(v)} /> @@ -311,7 +316,11 @@ export const FormFields = ({ value, field, error, register, control }) => { defaultValue={field.defaultValue} rules={field.rules} render={({ field: { onChange, value } }) => ( - + )} /> ) diff --git a/src/components/form/copyrightmodaltext.ts b/src/components/form/copyrightmodaltext.ts index 4558d0fc8..4efa7d134 100644 --- a/src/components/form/copyrightmodaltext.ts +++ b/src/components/form/copyrightmodaltext.ts @@ -61,7 +61,7 @@ export const copyrightModalText = { releasePublicDomain: `

This clause allows the work to be released to the public domain, effectively removing all copyright restrictions associated with it.

By releasing the work to the public domain, the creator permits anyone to use, modify, and distribute the work without needing to seek permission or pay royalties. This can be a strategic decision for creators who wish to maximize the work's exposure and accessibility.

-

Public domain release is often irrevocable, meaning once a work is released to the public domain, the creator cannot reclaim the rights. Therefore, it's crucial for Creators to carefully consider the implications before making such a decision, especially since it can be easily referenced on the blockchain itself. ("Announcements" made on social media or other privately-owned platforms often do not constitute

+

Public domain release is often irrevocable, meaning once a work is released to the public domain, the creator cannot reclaim the rights. Therefore, it's crucial for Creators to carefully consider the implications before making such a decision, especially since it can be easily referenced on the blockchain itself. ("Announcements" made on social media or other privately-owned platforms may or may not be admissible as a declaration so it may be risky to assume so.

This option can be particularly beneficial for educational, cultural, or philanthropic purposes, contributing to the broader public good by freely sharing creative works.

`, requireAttribution: ` From 9c0fb5d4363ed28d1d00ee3b202e7785300b4f5c Mon Sep 17 00:00:00 2001 From: ryangtanaka Date: Wed, 8 Jan 2025 11:28:11 -0800 Subject: [PATCH 06/13] preview canvas image fix --- src/components/form/FormFields.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/form/FormFields.jsx b/src/components/form/FormFields.jsx index 592e87e3a..32dd9a61c 100644 --- a/src/components/form/FormFields.jsx +++ b/src/components/form/FormFields.jsx @@ -193,8 +193,7 @@ export const FormFields = ({ value, field, error, register, control }) => { position: 'relative', width: '100%', maxWidth: '618px', - height: '382px', - maxHeight: '382px', + aspectRatio: '618/382', backgroundColor: 'black', overflow: 'hidden', } From afc908f80917a0d40700068711526bf409645765 Mon Sep 17 00:00:00 2001 From: ryangtanaka Date: Fri, 31 Jan 2025 17:49:52 -0800 Subject: [PATCH 07/13] faq page update --- src/pages/faq/index.jsx | 351 +++++++++++++++++++++++++++++--- src/pages/faq/index.module.scss | 8 +- 2 files changed, 333 insertions(+), 26 deletions(-) diff --git a/src/pages/faq/index.jsx b/src/pages/faq/index.jsx index de7a66382..5d6b4fac9 100644 --- a/src/pages/faq/index.jsx +++ b/src/pages/faq/index.jsx @@ -1,13 +1,26 @@ +import { useState } from 'react' // Import useState for state management import { Page } from '@atoms/layout' import { Button } from '@atoms/button' import styles from '@style' import { Line } from '@atoms/line' export const FAQ = () => { - const Question = ({ text, link }) => { + const Question = ({ text, answer }) => { + const [isOpen, setIsOpen] = useState(false) // State to manage visibility + + const toggleAnswer = () => { + setIsOpen(!isOpen) // Toggle the state + } + return (
  • - + + {isOpen && ( +
    + )}
  • ) } @@ -15,56 +28,344 @@ export const FAQ = () => { return (
    -

    FAQ

    +

    teia.art FAQ

      +
      +

      First, you will need a Tezos wallet and Tezos funds.

      +
      +
      +

      What is Tezos?

      +
      +

      Tezos (XTZ) is a liquid proof-of-stake cryptocurrency (LPoS). You can read more about it on the Wikipedia Article about Tezos.

      +
      +
      +

      Recommended Wallet Apps

      +
      +
        +
      • Temple wallet which is a browser extension similar to Metamask, also being able to connect to Ledger devices.
      • +
      • Kukai wallet, which is a browser wallet, being possible to connect making use of Direct Auth using Twitter credentials. Kukai also works on smartphones.
      • +
      +
      +
      +

      Where to Buy Tezos

      +
      +

      Minting on Teia only costs ~0.05 tezos. You can buy some tezos on an exchange site like Binance or Kraken. However, the exchange service might be limited depending on your country and location.

      +
      +
      +

      The Teia Fountain

      +
      +
      +
      +

      ⛲ Applying as an Artist

      +
      +

      Are you an artist who needs tez but can't get it? You can request a volunteer from the community to sponsor you in the #fountain channel on Discord.

      +
      +

      Please fill out this google form:

      + +
      +
      +

      ⛲ Volunteering as a Sponsor

      +
      +

      If you make some sales and would like to support other new artists you can send XTZ donations to the fountain multisig address KT1EsvmkijLKPQmcJMbjDeKRXdwky1LWvwpG

      +
      +
      +

      Common Wallet Errors

      +
      +
      +

      account doesn't exist error from tzkt.io

      +

      If your account on tzkt.io shows this, don't worry. It just means you don't have any transactions yet in your wallet. Once you receive some tezos it should go away.

      +
      +

      Prevalidation error in the temple wallet

      +

      This means you should refresh the page. Wait a couple of seconds for the transaction to go through and you will get the "applied" status.

      +
    +`} /> +
    +
    +

    mint

    +
    +
    +

    1: (verb) to create an OBJKT (NFT)

    +
    +
    +
    +

    Important Rules and Considerations

    +
    +

    If you mint NFTs on Teia, we expect you to respect the Core Values and especially note the detail on copyminting.

    +
    +

    Copyminting is the act of taking another's work and minting it as your own. It also includes the act of minting the same work twice, either on the same or separate platforms/blockchains. Your account will get restricted if you do this.

    +
    +

    Please note that minting the same media file twice, even accidentally, may lead to an account restriction! If you made a mistake and want to re-mint your OBJKT, make sure to burn the old one first! (How to burn)

    +
    +

    If your account gets restricted, check how to unrestrict it.

    +
    +
    +

    Step-by-Step Guide

    +
    +

    Minting is the operation of creating an NFT - at this point, you define the quantity of the NFT and information about it such as title and description. Once created, you will choose the number you want to make available and a price - this is a Swap operation.

    +
    +

    It might be useful to prepare a text file with all the information you will need for minting - if the minting operation is interrupted, you might lose what you typed in. OGs know from experience how frustrating it can be, especially if you wrote a classy and long description without saving a copy.

    +
    +
      +
    1. +

      You should have already created a wallet (we recommend Temple or Kukai). The wallet needs to have enough funds to mint. Click on “Sync". Your browser will show a pop-up asking you to sync with your wallet.

      +
      +

      sync button

      +

      beacon wallet popup

      +
    2. +
    3. +

      Approve the sync with your wallet.

      +
    4. +
      +
    5. +

      Click the "Mint" link in the hamburger drop-down menu.

      +
      +

      minting page white

      +
    6. +
      +
    7. +

      Fill out the information for your OBJKT. Because all this information is stored on the Tezos blockchain, the edition size (quantity) you set is final; you can't add (although you can reduce by burning). Title, descriptions, tags, and royalties are also final. You price the OBJKT (a Swap operation) after the minting. You can upload display images/gifs depending on the media type (e.g., for mpgs).

      +

      You can also select a license (default is None (all rights reserved)) and a language.

      +
    8. +
    +
    +
    +

    Text Mints on Teia

    +
    +

    The Teia NFT marketplace now supports text mints of mimetype: text/plain. This allows for stories, poems, ASCII, and similar types of text-based art. The token's content is stored in IPFS.

    +
    +
    +

    How to Mint Text

    +
    +
      +
    1. A new field on the minting page: "This is a text mint." Check this box.
    2. +
    3. The text mint input will automatically hide and replace the description box.
    4. +
    5. You will see the following fields on the minting form: +
        +
      • A checkbox for "Monospace Font Required."
      • +
      • There is a text area labeled "Typed Art Input." Depending on the monospace font required checkbox value, the text area renders the monospace (Iosevka font) or non-monospace (Source Sans Pro font).
      • +
      +
    6. +
    7. As you type text into the text area, a rendered preview of that text is displayed below it.
    8. +
    9. The preview page is displayed once you click the "Submit" button.
    10. +
    +
    +

    Note: The "monospace" tag is automatically added. The cover and thumbnail images are automatically generated based on the text input and the font selected. The description will also automatically be replaced by the text mint input.

    +
    +

    You can view an example: OBJKT 850488

    +
    +

    Source Sans Pro was selected for text mints as it's the default font (non-mono) on Objkt.com. This ensures text is encoded correctly and displayed as intended on Objkt.com and Teia.art. Currently, it seems that Objkt.com does not provide much monospace support for text mints, and a feature request has been raised here: https://roadmap.objkt.com/b/software-feature-request/use-a-monospaced-font-for-text-tokens/

    + +`} /> +
    +
    +

    Settings > Config

    +
    +
    +

    Profile information is useful in a number of ways. Most importantly, it can identify you to your potential collectors. Your profile details are saved with the Subjkt contract. The Profile page is where you update these, and it also links to the tzprofiles site so you can add that information.

    +
    +

    To edit your profile, make sure you've synced your wallet with Teia. Click the menu icon or go to: https://www.teia.art/subjkt

    +
    +

    +
    +

    .. then click on the Profile option

    +
    +

    full menu showing - profile highlighted

    +
    +

    Add a username, description, and choose an image for your profile pic. The profile pic may take a few moments to show up. Because it shows with a circular crop, you may have to adjust your initial picture and add it again.

    +
    +

    IMPORTANT When configuring your username, please don't use any special characters or spaces. It's also case-sensitive, so we recommend ALL LOWERCASE.

    +
    +

    profile page - fields highlighted

    +
    +

    When you click Save Profile, your wallet will open so you can complete a transaction which saves the profile information.

    +
    +

    profile and tzprofile copy

    +
    + +`} /> +
    +

    How to Swap 🔃

    +
    +

    1: (noun) an act, instance, or process of exchanging one thing for another

    +

    2: (verb) to set a price for your OBJKT

    +
    +

    If you have just minted some OBJKTs or you have unsold OBJKTs, it's time to Swap them - that means pricing some or all, for collectors to buy.

    +
    +

    Note - you can't swap OBJKTs that are already swapped, have already been collected, or if you don't have enough tez to pay the fees. You won't see Swap, Burn, Transfer options or be able to cancel swaps if you haven't synced the account that owns them.

    +
    +

    You don't need to swap all of the OBJKTs you own. Many artists like to keep one or two, either as 'artist proofs' or for gifting etc.

    +
    +

    Pricing is a tricky area that can be based on how big the edition size is, how well known and liked you are for your artwork, and how well you market it. Another consideration is how much you want for the work, not considering collectors and the current market. Pricing consistently and with some thought will influence some collectors.

    +
    +

    If you're considering pricing very low (0.01 tez, for example) or free, consider the fact that bots or bottom-dwelling flippers may buy many (sometimes all). When collectors view the OBJKT history, they will see the churn of low price activity that such flippers create, and it can reflect badly on how responsible collectors will view both the work and you as an artist. You can give away manually or try to regulate flipper action by swapping in blocks at different times (this also helps collectors in different time zones).

    +
    +

    Step-by-Step Guide

    +
      +
    1. +

      Click on your OBJKT's link to see the details. If you are synced to your wallet, you should see the "Swap" option next to History. (If you don’t see these options, then you have to sync your wallet again.)

      +
    2. +
    3. +

      Click on Swap.

      +
    4. +
    5. +

      Input how many OBJKTs out of your edition that you want to set for sale. For example, if you have 10 and you want to keep 1 and sell 9, then input 9. If you want to sell all of them, input 10.

      +
    6. +
    7. +

      Input how much each edition should cost in Tezos.

      +
    8. +
    9. +

      Click the "swap" button. You will be prompted to approve the transaction in your wallet app.

      +
    10. +
    11. +

      The user interface will update you on the transaction, or you can check in your wallet (look at 'activity' in Temple wallet). Once the transaction approves, your OBJKT/s are for sale to collectors. Go out and tell the Twitter world...

      +
    12. +
    +
    +

    How Can I Track What I've Sold?

    +

    You can use the tools hictory or hicdex: Just enter your wallet address and see your last sales in chronological order!

    +
    +

    How Can I Get Notifications for When I Sell Something?

    +

    You can use the Cryptonoises bot [https://cryptonoises.com/] developed by Andrii Bakulin. It works with both Telegram and Discord to get a notification every time something sells.

    + +`} /> +
    +

    1: (verb) to "delete" your OBJKT

    +
    +

    Transactions on the blockchain are irreversible, so you can't "delete" them. The "burn" button sends the OBJKT to the burn address - tz1burnburnburnburnburnburnburjAYjjX, or you can send it yourself using your wallet app. The burn address is an open address that nobody owns a key to, so objkts are never retrievable.

    +

    If you are burning the objkt because you made a mistake and want to remint it, make sure there are no other owners - you can only burn those you own, so you will need to ask those collectors to burn those objkts before you can remint.

    +
    +

    To Burn an OBJKT:

    +
      +
    1. +

      Make sure your wallet app is synced with Teia.

      +
    2. +
    3. +

      Make sure you cancel the swap of the OBJKT so it can be available in your wallet when you are ready to burn it. The user interface will show you how many you have available for burning. Think very hard about how many you'll burn - you can't undo this.

      +
      +

      burn screen

      +
    4. +
    5. +

      Press the burn button. Your wallet app will prompt you to confirm the transaction. Once the transaction completes, your wallet app will show the OBJKT as transferred to the burn address. The History tab will show a Burn transaction (and the fact that it is a transfer from your wallet to the burn wallet).

      +
      +

      burning

      +

      burn successful

      +
    6. +
    7. +

      You can also send the OBJKT to a burn address directly from your Tezos wallet. The address is: tz1burnburnburnburnburnburnburjAYjjX.

      +
    8. +
    +
    +

    Note: If you burn all of the objkts that were minted, the objkt will disappear from your profile. If someone buys one of your editions, even if you burn the rest of them, the OBJKT won't disappear from your profile.

    + +`} /> +
    +

    How to Sell an OBJKT Created by Another Artist

    +

    If you've collected another artist's OBJKT, then you own the right to resell it. This is also referred to as placing your OBJKT on the secondary market. It's much the same as swapping one of your own creations, although a royalty will be paid to the artist.

    +
    +

    Step-by-Step Guide

    +
      +
    1. +

      Make sure your wallet is synced.

      +
    2. +
    3. +

      Load your account page on Teia.

      +
    4. +
    5. +

      Click on "collection" and click on the OBJKT you want to resell.

      +
    6. +
    7. +

      Click on the "listings" tab to see all of the owners and sellers.

      +
    8. +
    9. +

      Click on "swap" and set a price for your OBJKT. Remember - if there are royalties, that percentage will go to the artist, so consider that in the pricing.

      +
    10. +
    11. +

      Click on the "swap" button and confirm the transaction in your wallet app.

      +
    12. +
    +
    +

    IMPORTANT: Once swapping something up for sale, it is held in the Teia escrow wallet while it is "on the market." Therefore, the OBJKT will disappear from your collections. Don't worry; it's still up for sale!

    +
    +
    +

    How Can I Track What I've Sold?

    +

    You can use the tools on hicdex.com to track transaction history.

    +
    +

    How Can I Get Notifications When I Sell Something?

    +

    You can use the Cryptonoises Telegram bot [https://cryptonoises.com/] to get a notification every time something sells. We have Andrii Bakulin to thank for this very useful tool. Support him if you are able.

    + +`} /> - -
    - -
    - +
    +
    +

    GitHub Documents (Open Source)

      For general questions, check out the General FAQ page.

      +`} /> If you're having issues, visit the Troubleshooting Guide.

      +`} /> Explore tools created by the community:

      + +`} /> Stay safe by following these tips:

      +
        +
      • Never share your private key.
      • +
      • Use trusted wallets and platforms.
      • +
      • Enable two-factor authentication (2FA) where available.
      • +
      +`} />
    diff --git a/src/pages/faq/index.module.scss b/src/pages/faq/index.module.scss index 5c6b99c16..3cc799d49 100644 --- a/src/pages/faq/index.module.scss +++ b/src/pages/faq/index.module.scss @@ -21,6 +21,12 @@ } } +.faq__container li button { + font-size: 1.5em; + font-weight: bold; + text-decoration: underline; +} + .faq__container:last-of-type { margin-top: 20px; @@ -37,7 +43,7 @@ } .faq__outer__container { - padding-top: 80px; + padding-top: 2em; width: 100%; @include respond-to('desktop') { From 7b6bd2475cce066e239890374bf5b9a7765d29e0 Mon Sep 17 00:00:00 2001 From: ryangtanaka Date: Fri, 31 Jan 2025 18:37:36 -0800 Subject: [PATCH 08/13] copyright clauses faq --- src/pages/faq/index.jsx | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/pages/faq/index.jsx b/src/pages/faq/index.jsx index 5d6b4fac9..a9228ebc3 100644 --- a/src/pages/faq/index.jsx +++ b/src/pages/faq/index.jsx @@ -325,6 +325,53 @@ export const FAQ = () => {

    How Can I Get Notifications When I Sell Something?

    You can use the Cryptonoises Telegram bot [https://cryptonoises.com/] to get a notification every time something sells. We have Andrii Bakulin to thank for this very useful tool. Support him if you are able.

    +`} + /> + +
    +

    TEIA's Copyright Features©️

    +

    TEIA empowers artists to attach copy and usage rights clauses to each minted OBJKT (NFT). These clauses are determined and declared by the artist at the time of minting. If you are interested in using this feature, it is essential to carefully read and understand the descriptions, explanations, and implications of each option before proceeding.

    +
    +

    The primary purpose of this feature is to enable artists to sell usage rights for their works in a transparent, legal, and fair manner. The blockchain facilitates this process by providing clear, objective, and easily traceable documentation of the agreement and the involved parties.

    +
    +

    Collectors may acquire these rights for purposes such as broadcasting, reproduction, merchandise sales, soundtracks, game assets, etc. TEIA DAO acts as a neutral platform that facilitates these agreements but does not intervene in or enforce the terms of the agreements. Please note that support for these clauses may vary across platforms, as the data is minted on-chain but not all platforms may choose to display or honor it.

    +
    +

    Disclaimer: TEIA is not a legal entity, organization, or institution with the authority to enforce laws or resolve disputes. The agreements attached to each mint (NFT) constitute a direct contractual relationship between the artist (licensor) and the collector (licensee). The terms of these agreements are determined at the time of minting and must be resolved through mutually agreed-upon means in the event of a dispute. Both parties are responsible for conclusively proving ownership of the relevant wallet(s) if required.

    +
    +

    Step-by-Step Guide

    +
      +
    1. +

      Sync Your Wallet: Ensure your wallet is synced with TEIA and that it is the correct wallet address you wish to associate with the agreements.

      +
    2. +
    3. +

      Navigate to "Mint": Go to the "Mint" section to begin creating your OBJKT.

      +
    4. +
    5. +

      Select "Custom License": Fill in the required details for your OBJKT, then choose "Custom License" from the License menu.

      +
    6. +
    7. +

      Define Your Terms: Review the available options for copyright clauses and permissions. Each option includes detailed explanations—read them thoroughly to select the agreement that best suits your work. If additional details or modifications are needed, use the Addendum section to customize the agreement.

      +
    8. +
    9. +

      Mint Your OBJKT: Once the terms are finalized, proceed to mint your OBJKT as usual.

      +
    10. +
    11. +

      Verify the Agreement: After minting, visit the "Asset" page to confirm that the clauses were saved correctly. Your work, along with its associated agreements, is now permanently registered on-chain. This makes it searchable on any platform that supports the metadata format. (View Example)

      +
    12. +
    +
    +

    Important Notes

    +
      +
    • Artist Responsibility: As the artist, you are responsible for clearly defining the terms of the agreement and ensuring they align with your intentions for the work.
    • +
    • Collector Responsibility: Collectors must review and agree to the terms before purchasing the OBJKT. Failure to comply with the terms may result in legal consequences.
    • +
    • Dispute Resolution: In the event of a dispute, both parties are encouraged to resolve the matter amicably. If necessary, seek legal counsel to enforce or interpret the terms of the agreement.
    • +
    +
    +

    By using TEIA's copyright features, you acknowledge and agree to these terms. TEIA provides the tools to facilitate these agreements but assumes no liability for their enforcement or interpretation.

    + `} /> From 4df6007632a298632b63016bf00b90cdabdd0266 Mon Sep 17 00:00:00 2001 From: ryangtanaka Date: Sat, 1 Feb 2025 13:39:36 -0800 Subject: [PATCH 09/13] policy and terms update --- src/components/footer/index.module.scss | 1 + .../header/feed_toolbar/FeedToolbar.jsx | 20 ++- src/components/header/main_menu/MainMenu.jsx | 26 ++- src/index.jsx | 7 +- src/lang/en/about.md | 49 ++++-- src/lang/en/codeofconduct.md | 161 ++++++++++++++++++ src/lang/en/corevalues.md | 107 ++++++++++++ src/lang/en/privacypolicy.md | 41 +++++ src/lang/en/terms.md | 83 +++++++++ src/pages/codeofconduct/index.jsx | 26 +++ src/pages/codeofconduct/index.module.scss | 0 src/pages/corevalues/index.jsx | 26 +++ src/pages/corevalues/index.module.scss | 0 src/pages/dao/tabs/Parameters.jsx | 122 +++++++++---- src/pages/faq/index.jsx | 4 +- src/pages/home/feeds/friends-feed.jsx | 2 +- src/pages/privacypolicy/index.jsx | 26 +++ src/pages/privacypolicy/index.module.scss | 0 src/pages/terms/index.jsx | 25 +-- 19 files changed, 653 insertions(+), 73 deletions(-) create mode 100644 src/lang/en/codeofconduct.md create mode 100644 src/lang/en/corevalues.md create mode 100644 src/lang/en/privacypolicy.md create mode 100644 src/lang/en/terms.md create mode 100644 src/pages/codeofconduct/index.jsx create mode 100644 src/pages/codeofconduct/index.module.scss create mode 100644 src/pages/corevalues/index.jsx create mode 100644 src/pages/corevalues/index.module.scss create mode 100644 src/pages/privacypolicy/index.jsx create mode 100644 src/pages/privacypolicy/index.module.scss diff --git a/src/components/footer/index.module.scss b/src/components/footer/index.module.scss index a92c7af21..ef3722a72 100644 --- a/src/components/footer/index.module.scss +++ b/src/components/footer/index.module.scss @@ -91,6 +91,7 @@ .copyright { grid-area: Copyright; + text-align: left; } .state_buttons { diff --git a/src/components/header/feed_toolbar/FeedToolbar.jsx b/src/components/header/feed_toolbar/FeedToolbar.jsx index 8f7469c0f..413314803 100644 --- a/src/components/header/feed_toolbar/FeedToolbar.jsx +++ b/src/components/header/feed_toolbar/FeedToolbar.jsx @@ -8,10 +8,10 @@ import { SingleViewIcon, MasonryIcon, ChevronIcon } from '@icons' import { Button } from '@atoms/button' import { useLocalSettings } from '@context/localSettingsStore' -import { useLocation, useNavigate } from 'react-router' +import { useLocation, useNavigate, useParams } from 'react-router' import { Line } from '@atoms/line' import { shallow } from 'zustand/shallow' -import { DEFAULT_START_FEED } from '@constants' +import { useUserStore } from '@context/userStore' // const MediaFilter = ({ label, tagline }) => { // return ( @@ -26,7 +26,7 @@ const locationMap = new Map([ ['/feed/sales', 'Recent Sales'], ['/feed/random', 'Random'], ['/feed/newobjkts', 'New OBJKTs'], - ['/feed/friends', 'Friends'], + ['/feed/friends*', 'Friends'], // separator ['---fund_feeds', 'fund_feeds'], ['/feed/art4artists', 'Art4Artists'], @@ -62,9 +62,12 @@ export const FeedToolbar = ({ feeds_menu = false }) => { ) const location = useLocation() const feedLabel = - locationMap.get(location.pathname) || startFeed || DEFAULT_START_FEED + [...locationMap.entries()].find(([key]) => + location.pathname.startsWith(key.replace('*', '')) + )?.[1] || 'Sort' // Default to "Sort" if no match is found const navigate = useNavigate() + const walletAddress = useUserStore((st) => [st.address], shallow) // TODO: finish the filtering logic // const filters = false @@ -98,7 +101,14 @@ export const FeedToolbar = ({ feeds_menu = false }) => { ) } return ( - ) diff --git a/src/components/header/main_menu/MainMenu.jsx b/src/components/header/main_menu/MainMenu.jsx index 5006f72a8..761e2e075 100644 --- a/src/components/header/main_menu/MainMenu.jsx +++ b/src/components/header/main_menu/MainMenu.jsx @@ -34,7 +34,31 @@ export const MainMenu = () => { {/* */} - + + + + +
    diff --git a/src/index.jsx b/src/index.jsx index d17c4f8b3..2deae8e10 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -75,6 +75,9 @@ import { Preview } from '@components/preview/index' import MintForm from '@components/form/MintForm' import { ListsFeed } from '@pages/home/feeds/lists-feed' import { MidiFeed } from '@pages/home/feeds/mime-type-feed' +import { CodeOfConduct } from '@pages/codeofconduct' +import { CoreValues } from '@pages/corevalues' +import { PrivacyPolicy } from '@pages/privacypolicy' const display_routes = ( <> @@ -132,7 +135,9 @@ const router = createBrowserRouter( } /> } /> } /> - + } /> + } /> + } /> } /> }> } /> diff --git a/src/lang/en/about.md b/src/lang/en/about.md index 448c7340a..e5cc9b059 100644 --- a/src/lang/en/about.md +++ b/src/lang/en/about.md @@ -12,7 +12,13 @@ --- -[Core Values](https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions#core-values) /[Code of Conduct](https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions#code-of-conduct) /[Terms and Conditions](https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions#terms-and-conditions)/[Account Restrictions/Content Moderation](https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions#content-moderation) +[Core Values](https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions#core-values) + +[Code of Conduct](https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions#code-of-conduct) + +[Terms and Conditions](https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions#terms-and-conditions) + +[Account Restrictions/Content Moderation](https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions#content-moderation) @@ -20,15 +26,23 @@ ## Links -- Documentation: [wiki.teia.art](https://github.com/teia-community/teia-docs/wiki) -- Blog: [blog.teia.art](https://blog.teia.art) -- Announcements and Updates: [Twitter](https://twitter.com/TeiaCommunity) -- Join the community: [discord](https://discord.com/invite/7pZrPCcgnG) -- Report Harassment or Scams via the [Report Form](https://docs.google.com/forms/d/e/1FAIpQLSeuBmNJjTiROSbHXXiQ5e-ia6fFywHKZ7Dj4-7sZtyltGY3yA/viewform) -- Report Bugs via a [Github issue](https://github.com/teia-community/teia-ui/issues) -- DAO Agora/Forum: [discourse.teia.art](https://discourse.teia.art/) -- Code: [Teia Github](https://github.com/teia-community) -- Community Curation: [@TeiaArt](https://twitter.com/TeiaCommunity) +Documentation: [wiki.teia.art](https://github.com/teia-community/teia-docs/wiki) + +Blog: [blog.teia.art](https://blog.teia.art) + +Announcements and Updates: [Twitter](https://twitter.com/TeiaCommunity) + +Join the community: [discord](https://discord.com/invite/7pZrPCcgnG) + +Report Harassment or Scams via the [Report Form](https://docs.google.com/forms/d/e/1FAIpQLSeuBmNJjTiROSbHXXiQ5e-ia6fFywHKZ7Dj4-7sZtyltGY3yA/viewform) + +Report Bugs via a [Github issue](https://github.com/teia-community/teia-ui/issues) + +DAO Agora/Forum: [discourse.teia.art](https://discourse.teia.art/) + +Code: [Teia Github](https://github.com/teia-community) + +Community Curation: [@TeiaArt](https://twitter.com/TeiaCommunity) --- @@ -52,11 +66,16 @@ The Teia Marketplace Interface and marketplace contract are [code forks](https:/ The [marketplace fees](https://github.com/teia-community/teia-docs/wiki/Marketplace-Fees) are set to 2.5%. -### Smart Contracts: -- **FA2 Token Contract:** [KT1RJ6PbjHpwc3M5rw5s2Nbmefwbuwbdxton](https://tzstats.com/KT1RJ6PbjHpwc3M5rw5s2Nbmefwbuwbdxton) by [hicetnunclab2000](https://github.com/hicetnunc2000/objkt-swap) -- **Minting Contract:** [KT1Hkg5qeNhfwpKW4fXvq7HGZB9z2EnmCCA9](https://tzkt.io/KT1Hkg5qeNhfwpKW4fXvq7HGZB9z2EnmCCA9/operations/) by [hicetnunclab2000](https://github.com/hicetnunc2000/objkt-swap) -- **Marketplace Contract:** [KT1PHubm9HtyQEJ4BBpMTVomq6mhbfNZ9z5w](https://tzkt.io/KT1PHubm9HtyQEJ4BBpMTVomq6mhbfNZ9z5w/operations/) by [Teia community](https://github.com/teia-community/teia-smart-contracts/blob/main/python/contracts/teiaMarketplace_v1.py) - audited by [Inference AG](https://github.com/InferenceAG/ReportPublications/blob/master/Inference%20AG%20-%20Teia%20community%20-%20marketplace%20%26%20multisig%20-%20v1.0.pdf) -- **Marketplace Contract Admin:** [KT1PKBTVmdxfgkFvSeNUQacYiEFsPBw16B4P](https://tzkt.io/KT1PKBTVmdxfgkFvSeNUQacYiEFsPBw16B4P/operations/) - [multisig contract](https://multisign.onrender.com/) developed by the Teia Community +--- +## Smart Contracts: + +**FA2 Token Contract:** [KT1RJ6PbjHpwc3M5rw5s2Nbmefwbuwbdxton](https://tzstats.com/KT1RJ6PbjHpwc3M5rw5s2Nbmefwbuwbdxton) by [hicetnunclab2000](https://github.com/hicetnunc2000/objkt-swap) + +**Minting Contract:** [KT1Hkg5qeNhfwpKW4fXvq7HGZB9z2EnmCCA9](https://tzkt.io/KT1Hkg5qeNhfwpKW4fXvq7HGZB9z2EnmCCA9/operations/) by [hicetnunclab2000](https://github.com/hicetnunc2000/objkt-swap) + +**Marketplace Contract:** [KT1PHubm9HtyQEJ4BBpMTVomq6mhbfNZ9z5w](https://tzkt.io/KT1PHubm9HtyQEJ4BBpMTVomq6mhbfNZ9z5w/operations/) by [Teia community](https://github.com/teia-community/teia-smart-contracts/blob/main/python/contracts/teiaMarketplace_v1.py) - audited by [Inference AG](https://github.com/InferenceAG/ReportPublications/blob/master/Inference%20AG%20-%20Teia%20community%20-%20marketplace%20%26%20multisig%20-%20v1.0.pdf) + +**Marketplace Contract Admin:** [KT1PKBTVmdxfgkFvSeNUQacYiEFsPBw16B4P](https://tzkt.io/KT1PKBTVmdxfgkFvSeNUQacYiEFsPBw16B4P/operations/) - [multisig contract](https://multisign.onrender.com/) developed by the Teia Community diff --git a/src/lang/en/codeofconduct.md b/src/lang/en/codeofconduct.md new file mode 100644 index 000000000..f32071aa8 --- /dev/null +++ b/src/lang/en/codeofconduct.md @@ -0,0 +1,161 @@ +# **`Code of Conduct`** + +`Teia is a community of artists, creators, and collectors from all around the world, who come together to grow and inspire others. All participants in the community are expected to act lawfully, honestly, ethically, and in the best interest of the community. All users are expected to follow the rules and guidelines laid out in this document, acting against this CoC in any of Teias spaces might result in account restrictions or bans.` + +## **`1. Contribute and Help Improve the Community`** + + `1.1 Look for ways to contribute and find positive solutions. Stay open minded and empathetic around areas of improvements. And take initiative to help out where you can.` + + `1.2 Try to share your knowledge with the community.` + + `1.3 Your participation matters. If you feel that you or the group you identify with is underrepresented or does not have a voice in the community, know that you are welcome here. Be the first to fill that gap, invite your peers, and make yourself heard.` + + `1.4 Bugs and security flaws in the platform, blockchain or smart contract should be disclosed responsibly, according to regulations and best practices regarding those procedures.` + +## **`2. Unacceptable Behavior`** + +`We do not condone harassment or abuse against any member in any community environment, online or offline, for any reason. This includes the usage of Teia Infrastructure and smartcontracts related to Teia. Abusive actors can get banned from any Teia related spaces.` + +`People with significant experience and/or connections within the community are expected to behave with special care with regards to their privilege. i.e. negative comments and behaviour from them towards others may carry an unintended backlash or harm.` + +#### `Harassment Includes` + +`2.1 targeting individuals in a manner that makes them feel uncomfortable, unwelcome, or afraid.` +`2.2 offensive verbal, visual or text based comments related to gender, age, sexual orientation, disability, neurotype, health related issues, income level, mental health status, trauma, physical appearance, body size, race, ethnicity, religion.` +`2.3 deliberate intimidation, stalking, following, sustained disruption of conversation.` +`2.4 Violence, threats of violence or violent language directed against another person.` +`2.5 Posting or displaying sexually explicit or violent material outside of the context of artistic expression.` +`2.6 Posting or threatening to post other people's personally identifying information ("doxxing").` +`2.7 Inappropriate photography or recording.` +`2.8 Inappropriate physical contact, unwelcomed sexual attention or advances, inappropriate touching, groping. You should always have someone's active consent before touching them.` + +#### `Abuse Includes` + +`2.9 Using one's authority, reputation or knowledge to intimidate or threaten others.` +`2.10 Maliciously causing someone to doubt their own perceptions, senses, or understanding with the objective to win an argument or force someone to behave the way you want.` + +#### `Other Unacceptable Behavior` + +`2.11 Impersonating others and plagiarizing` +`2.12 Spamming or vandalizing any of Teias spaces, online or offline, on-chain or off-chain.` +`2.13 Scamming and social engineering.` +`2.14 Sustained disruption of community events, including talks and presentations.` +`2.15 Advocating for, or encouraging any of the above behavior.` + +### `Consequences of Unacceptable Behavior` + +`Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated.` + +`Anyone asked to stop unacceptable behavior is expected to comply immediately.` + +`If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the platforms and spaces associated with the Teia community without warning (and without refund in the case of a paid event).` + +`If a community manager does not actively investigate any reported and unacceptable behavior fairly, they will need to be held responsible and might be removed from their position.` + +## **`3. Fairplay on the Marketplace`** + +`3.1 Collectors should voluntarily refrain from using automated tools for collecting, from hindering other participants from collecting and from interfering with the site and the smart contracts in any way.` + +`3.2 Collectors should voluntarily refrain from collecting excessively such as collecting large amounts of a “free” or low priced edition. Participants should apply their discretion as to what counts as “excessive”.` + +`3.3 Artists have certain moral rights to work they create. We believe Art and also NFTs are more than simple financial assets and should be treated as such. owners of tokens should refrain from using NFT mechanisms such as burning in ways that could impact the creators moral rights to their work or reputation or endager the digital artwork/concept without the creators consent.` + +`3.4 Users are expected to refrain from any market manipulation such as wash trading and conspiring to artificially increase the perceived demand or price.` + +`3.5 Users should voluntarily refrain from minting other peoples work even if consent has been given by the original creator. While there are legitimate reasons for minting pieces by other artists for them (such as gallery projects) this goes against the spirit of NFTs and has proven to be problematic for various reasons. Gallery projects are asked to mint other artists work via Teia’s collab contracts with the main creator as co-collaborator.` + +## **`4. Reporting Guidelines`** + +`4.1 If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible either via the report form, the discord channel #report or a mail to "info@teia.art"` + +`4.2 For reporting copymints, please use the discord channel #report-copyminters or send a mail to “info@teia.art”. If you report accounts via mail, please make sure to include: The full longform Tezos address of the reported account, and evidence of unacceptable behavior.` + +`4.3 Community moderators are available to help those experiencing unacceptable behavior feel safe.` + +`4.4 In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress.` + +`4.5 If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify Teia with a concise description of your grievance via mail. Your grievance will be handled in accordance with our existing governing policies.` + +## **`5. Content Rules and Teia Profile Restrictions`** + +`The Teia community reserves its right to moderate content and ban/restrict wallets from the marketplace to make Teia a fair and safe experience for all.` + +`The content moderation team operates on the following Terms and works voluntarily to protect TEIA collectors and artists from copyminting and other types of malicious activity.` + +`Please understand their role and that processes like this do generate mistakes. The team investigates when alerted through the #report-copyminters channel in the TEIA Discord. Please respect their work, and help them by being courteous and accurate with the information that will help your inquiry.` + +`Various other Tezos marketplaces also use the TEIA restricted list of accounts, which means that once TEIA restricts an account, other NFT marketplaces will likely follow suit. Note that other marketplaces, even those using the same minting contracts, may have different Terms and Codes of Conduct, and so account restrictions may sometimes differ between platforms that display the same works.` + +`Since TEIA is a decentralized application, restricted OBJKTs are only restricted on Teia's user interface, meaning that they are still available through APIs and on-chain data.` + +### `5.1 Types of Profile Restrictions` + +**`“Restricted account”`** `Accounts that TEIA restricts are labeled “restricted account,” and OBJKTs that a restricted account has minted are labeled “restricted OBJKT” in the marketplace.` + +**`“Account under review”`** `Accounts that are marked as “under review” have been flagged for further investigation or minor misbehaviour or general red flags. Accounts under review can still trade on the Teia UI. Users whose account has been put under review are asked to come to the #report-copyminters channel on the Teia discord for clarification.` + +### `5.2 Copyright and Intellectual Property` + +`As artists and collectors of art, we want to acknowledge and protect intellectual property as it is crucial for our integrity and work but we also acknowledge that some forms of art need to use the works of others (i.e. remixes, tributes, quotes).` + +*`“Artists should avoid uses of existing copyrighted material that do not generate new artistic meaning, being aware that a change of medium, without more, may not meet this standard.”`*`*` + +*`“The use of a preexisting work, whether in part or in whole, should be justified by the artistic objective, and artists who deliberately repurpose copyrighted works should be prepared to explain their rationales both for doing so and for the extent of their uses”`*`[*]` + +*`“Artists should avoid suggesting that incorporated elements are original to them, unless that suggestion is integral to the meaning of the new work.”`* `[*]` + +`We suggest not to mint content that is in the public domain or under other similar licenses that allow reselling without creative changes or using it as a way of artistic expression.` + +`While some content is free to be used and if specified in the license even commercially, there are problematic implications that come with minting unchanged content and selling it as a NFT, such as occurring double mints if multiple people mint the same public domain content (see Terms & Conditions).` + +`When creating a tribute piece to somebody else’s work, an artist should get written permission from the creator of the original, clearly label it as a hommage and name the original creator, unless there is an articulable aesthetic basis for not doing so (i.e. pastiche / sampling / collage / satire / public domain source).` + +`[*] taken from page 11 of the “Code of Best Practices in Fair Use for the Visual Arts” by Patricia Aufderheide and Peter Jaszi, 2015)` + +### `5.3 Proper Content Classification` + +**`NSFW content:`** `explicit, overtly sexual or violent imagery or potentially disturbing (“Not safe for work”) material should always be tagged as “NSFW” in the provided check box in the minting interface. This content is not banned but will be moderated differently on the platform.` + +**`Photosensitive content:`** `Content that contains flashing/stroboscopic animations may cause harm to users and must be tagged accordingly with the checkbox provided in the minting UI to help make Teia a safe space for its users.` + +### `5.4 Possible Reasons for an account restriction:` + +**`Copyminting`**`: Minting another artist(s) work without their consent. Copyminting can also include works based on another artist's work, with minimal filters or modifications applied` + +**`Double minting`**`: Minting the same work more than once without artistic merit or an apparent reference for prospective buyers. Of every piece of content there should be only one NFT. Doublemints on multiple marketplaces, contracts or blockchains are treated as copymints. For pieces that are double-mints on the hicetnunc minting contract, this rule is enforced for objkts minted after 01.01.2022.` + +**`Infringed copyright`**`: The use of artists' work in part or whole in a way that is not in line with the license/copyright of said work or not defendable through artistic merit.` + +**`Plagiarism:`** `Implying authorship of work created by others; i.e. by copying, reproducing or using other peoples work as a base without clearly citing the source and giving credit within the work itself or within the description associated with the NFT. Exceptions can be made if the artistic merit lies within the practice of repurposing content.` + +**`Clear association with confirmed restricted accounts`**`: Ample evidence of being a person that engaged in restricted behavior. i.e. by funding (sending an account its initial funds) of restricted accounts, being funded by a restricted account or other clear evidence of association with restricted accounts.` + +**`Market Manipulation`**`: for example buying one's own tokens to artificially increase prices (“washtrading”).` + +**`Freeloading`**`: abusing the services or infrastructure of Teia in ways that put the platform in danger. Ie by minting excessive amounts of tokens in short periods of time. Cases like this don't necessarily result in a ban but Teia might need to reduce the impact on its infrastructure ie:. By unpinning the content from Teia's IPFS node.` + +**`Illegal Content:`** `Minting material that glorifies human rights violations or is solely pornographic without artistic expression or might otherwise put Teia in legal jeopardy. This applies especially but is not limited to cases of copied or slightly modified NSFW content stolen from third parties and depictions of sexualized underaged characters. NSFW material is generally allowed if classified properly.` + +**`Public domain content:`** `Accounts that mint public domain content or content under C00 or similar licenses without changes or adding new artistic meaning might get restricted or those tokens might get restricted from getting sold, especially if they are not clearly indicating the original author and license in the description. This is due to the complexity to verify if such NFTs are complying with the license of the original content and the copymint team having only limited resources to do that.` + +`This rule might get lifted in the future with the implementation of new systems of verification or moderation. If your artistic practice involves using public domain work without change, it might help to notify the copymint team prior to minting and discussing the individual case.` + +**`Missing classification of NSFW/Photosensitive content:`** `Teia might restrict accounts that mint NSFW or photosensitive material without properly classifying it upon mint, the team can also classify accounts or individual pieces after the mint.` + +**`Exploiting the marketplace contracts:`** `For example by circumventing royalties.` + +**`Gambling and scamming`**`: selling/using NFT tokens as a tool for scamming or gambling (i.e. prize scamming).` + +**`Violating the Terms of Service or Code of Conduct in other ways:`** `Mainly if it is overtly abusive to another group, invokes violence, or intimidates, harasses or impersonates.` + +### `5.5 Procedure if your Teia account has been restricted` + +`If you are banned, please don’t create new accounts to circumvent the account restriction but request for an unban first, those accounts might get automatically banned. If you want to keep on minting, please get in touch with the content moderation team first and discuss the way forward.` + +`Contesting restrictions can be made through the #report-copyminters channel in the TEIA Discord. It’s important to notice that errors are possible at this stage, and we apologize for such cases. We ask users to direct such issues exclusively through the channel.` + +`Unfortunately, the Content moderation team has to begin the process with a lack of trust, and you have to convince them that you are trustworthy. The most straightforward way to overturn a mistaken restriction is to engage with the team politely and honestly.` + +`Provide your account address and the reason for the dispute. Be prepared to show works in progress or versions of a work in question so the team can verify and determine if the restriction is mistaken. Having a well-used Twitter account, work is shown on your website, Instagram, Flickr, Tumblr, etc., that is your own will help.` + +`If the copymint team agrees that the account does not violate the TEIA CoC, the account will have its restricted or under-review status removed. It takes about 5 mins for any changes to the restricted list to go live.` \ No newline at end of file diff --git a/src/lang/en/corevalues.md b/src/lang/en/corevalues.md new file mode 100644 index 000000000..bc3bb992a --- /dev/null +++ b/src/lang/en/corevalues.md @@ -0,0 +1,107 @@ +### TEIA's Core Values + +`TEIA is an open, digital platform of ideas and works of creativity. It is an artwork made of artworks; Artists and collectors coming together as equal lovers of creativity in order to emancipate and democratize art.` + +`We want to elevate art, no matter how known or unknown the artist. We want to protect our art. We want to fill the blank canvas that is TEIA.` + +`TEIA is a self sustaining organization managed by the community for the community.` + +`TEIA is built and improved by its participants. We believe that we as a collective can be bigger than the sum of our members. We strive to improve TEIA in a decentralised manner. That means we can build and evolve everything at once, everything follows chaotic growth. This infinite process might at times look disorganized from the outside looking in, but it isn't: The community organizes itself; chaos creates beauty.` + +`We want, however, to protect and preserve the spirit of Teia. Those core values should guide our decisions moving forward in this rapidly evolving space. This manifesto, collectively written, tries to put this spirit into words.` + +# + +## **`§1 Inclusivity`** + +`1.1 We believe in a community for all users and all art forms:` + +`1.1.1 Inclusive for everyone, no matter your race, ethnicity, religion, class, culture, national background and citizenship status, sexual orientation, gender identity and expression, age, or mental or physical disability, neurotype, health related issues, income level, mental health status or trauma` +`1.1.2 Inclusive for all participants, no matter the social/economic status.` +`1.1.3 inclusive for all art forms and mediums including but not limited to: digital, analog, graphics, vr, video, audio, music, fiber, physical and the ones to come.` + +`1.2 We want to reach a parity in voice and contribution between people from all communities and sorts of privileges and locations. This needs to be reached through concrete action and leveraging power.` + +--- + +## **`§2 Respect`** + +`2.1 We believe in a community that respects one another’s dignity, ideas, thoughts and art.` + +`2.2 We respect our community and value each person's contribution.` + +`2.3 We understand that this is, and always will be, a work in progress and we are empathetic and patient with this process.` + +--- + +## **`§3 Community/Solidarity`** + +`3.1 We are an egalitarian community. Our community is not about rank, status, or popularity. It’s about contributing, building together, fostering connections, encouraging community interactions, providing support, and growing together.` + +`3.2 The community must ensure the freedom of the individual, but this freedom ends where it endangers the well-being of the community.` + +`3.3 We want to:` + +`3.3.1 Avoid displaying indications of rank, status, or popularity but are open to celebrating contributions of time and skill.` +`3.3.2 Build what benefits the whole community, not just a select few with the exception of accessibility features that enable underserved members.` +`3.3.3 Create systems that are inclusive to the community as a whole.` +`3.3.4 Aavoid systems that could be exclusive in any shape or form.` +`3.3.5 Protect the community and their intellectual property from threats.` + +--- + +## **`§4 Decentralization`** + +`We believe in shared ownership on the platform, no one should have exclusive rights over others.` + +`4.1 We believe in a platform that radically dismantles and democratizes the established art market and methods of distribution.` + +`4.2 Teia should remain open source. We aim to create open solutions and look for ways to limit gatekeeping and share knowledge wherever possible.` + +`4.3 We want to build a transparent platform that facilitates a rich ecosystem and integrates with the world around it. We encourage third party additions/tools for the Teia core as long they stay true to the spirit of Teia.` + +`4.4 We want to build a platform where important decisions are voted on in an open and fair process before being implemented. We want to:` + +`4.4.1 Encourage and secure open and free discussions around community voting.` +`4.4.2 Give all users fair rights in this voting process.` +`4.4.3 Encourage and help all members to participate in community votes.` + +`4.5 The community should respect and encourage all opinions, even if they are against the consensus. The individual should respect consensus reached by the community in the same way.` + +--- + +## **`§5 Simplicity and Accessibility`** + +`5.1 Teia should aim to be as accessible as possible. The creation of an account should be simple and fast and possible anonymously and without providing any personal information.` + +`5.2 Teia should not store or collect personal information about its members beyond their tezos addresses and user name and optional linked accounts.` + +`5.3 We want to provide a simple and easy-to-use platform for all users, including those with accessibility needs.` + +`5.4 We want to help those without access to the platform to get the ability to participate. (i.e. via donations for people who can’t afford to mint)` + +`5.5 We believe in providing access to useful tools for all members of the community.` + +--- + +## **`§6 Sustainability`** + +`We believe in sustainability. With technology evolving, we as a community need to evolve too and build towards a more viable future. We shall be mindful of the consequences of our actions and evaluate our decisions with that in mind, always pursuing the least destructive path.` + +`6.1 Things that may look responsible now may be problematic for us and everyone in the future. Lifecycle impacts must be considered.` + +`6.2 With that in mind, we should always be open to the possibility of changing the technological foundations of Teia in order to ensure it stays sustainable, transparent and accessible to everyone.` + +`6.3: Teia should find decentralised and long-lasting solutions for storing files associated with Tokens minted on Teia. The files need to always be accessible to the public no matter the future state of the platform.` + +--- + +## **`§7 Creativity`** + +`7.1 Creativity has no borders. We want to encourage and organize events that bring the global community together and create bonds and collaborations between us and contribute to shaping the future of art as whole.` + +`7.2 We want to encourage and help the development of new forms and shapes of art through collaborations between the users.` + +`7.3 We believe in providing an open and supportive space for all artists and collectors to express themselves freely and without limitations.` + +`7.4 Creativity needs freedom, we want to make sure there are as few restrictions as possible in place to make Teia a place of creativity without limitations but also ensuring the intellectual rights of creators/artists and complying with legal requirements as well as the wellbeing of Teia's communiity.` \ No newline at end of file diff --git a/src/lang/en/privacypolicy.md b/src/lang/en/privacypolicy.md new file mode 100644 index 000000000..437b6a86d --- /dev/null +++ b/src/lang/en/privacypolicy.md @@ -0,0 +1,41 @@ +# Privacy Policy for Teia DAO LLC + +At Teia, accessible from [https://teia.art/](https://teia.art/), one of our main priorities is the privacy of our visitors. This Privacy Policy document contains the types of information that are collected and recorded by Teia and how we use this information. This Policy applies to information we collect on the Platform and through your use of the Platform. Please, review this Policy carefully. By accessing or using the Platform, you agree to the terms of this Policy on behalf of yourself or the entity or organization that you represent. If you do not agree to any term in this Policy, you should refrain from further use of our Services. + +If you have additional questions or require more information about our Privacy Policy, do not hesitate to contact us. + +## 1\. User data + +Teia does not store personal data of its users however, it relies on data stored on decentralized storage solutions that are available to the public via either the Tezos blockchain IPFS and/or public indexers. + +Teia follows a standard procedure of using log files. These files log visitors when they visit websites. All hosting companies do this and are a part of hosting services' analytics. The information collected by log files includes internet protocol (IP) addresses, browser type, Internet Service Provider (ISP), date and time stamp, referring/exit pages, and possibly the number of clicks. These are not linked to any information that is personally identifiable. The purpose of the information is for analyzing trends, administering the site, tracking users' movement on the website, and gathering demographic information. Teia does **NOT** use any tracking 'cookies' like Google Analytics, Facebook Pixel, etc. + +## 2\. Third-Party Privacy Policies + +Teia's Privacy Policy does not apply to other service providers or websites. Thus, we are advising you to consult the respective Privacy Policies of these third-party ad servers for more detailed information. It may include their practices and instructions about how to opt-out of certain options. You can choose to disable cookies through your individual browser options. To know more detailed information about cookie management with specific web browsers, it can be found on the browsers' respective websites. + +We might disclose user information in response to Subpoenas or Court Orders or to Protect Rights and to Comply with Our Policies. + +## 3\. Children's Information + +Another part of our priority is adding protection for children while using the internet. We encourage parents and guardians to observe, participate in, and/or monitor and guide their online activity. + +Teia does not knowingly collect any Personal Identifiable Information from children under the age of 13\. If you think that your child provided this kind of information on our website, we strongly encourage you to contact us immediately and we will do our best efforts to promptly remove such information from our records. + +## 4\. Online Privacy Policy Only + +This Privacy Policy applies only to our online activities and is valid for visitors to our website with regard to the information that they shared and/or collect in Teia. This policy is not applicable to any information collected offline or via channels other than this website. + +## 5\. Accessing and Correcting your Information + +To request rectification or deletion of any information collected by us concerning your use of the platform, please contact **privacy@teia.xyz** or send a written communication to the following postal address: PO Box 852, Long Island Rd, Majuro. + +## 6\. DMCA + +The Digital Millennium Copyright Act (DMCA) sets forth a notification and counter-notification process initiated by a party complaining of alleged copyright infringement on the Platform. We may share information of the notifying, counter-notifying party, and any involved third parties, such as a collector, of an allegedly infringing artwork to facilitate communication between the relevant parties for the purposes of complying with or resolving a DMCA dispute or allegation of copyright infringement. Nothing in this Policy restricts our ability to: comply with applicable law, rules, or regulations, including the DMCA; comply with a civil, criminal, or regulatory inquiry, investigation, subpoena, or lawful court order; cooperate with law enforcement agencies about conduct we reasonably and in good faith believe may violate the law; protect our rights or our property; enforce our Terms of Service; or, prevent behavior that is (or that we think may be) illegal or unethical. + +## 7\. Consent and Terms of Use. + +By using our website, your usage, and any privacy dispute is subject to this Policy and our Terms of Use (link to Terms of Use). + +We will notify users of changes to this Privacy Policy by posting the amended terms on the Service in advance of the effective date of the changes. If you do not agree to the changes, you should discontinue your use of the Service prior to the time the modified privacy policy takes effect. If you continue using the Service after the modified privacy policy takes effect, you will be bound by the modified privacy policy. diff --git a/src/lang/en/terms.md b/src/lang/en/terms.md new file mode 100644 index 000000000..ef2ec562c --- /dev/null +++ b/src/lang/en/terms.md @@ -0,0 +1,83 @@ +### Terms of Service for TEIA Marketplace and TEIA DAO LLC + +Welcome to Teia Marketplace! + +These terms and conditions outline the rules and regulations for the use of Teia’s marketplace, hosted at [https://teia.art](https://teia.art), and operated by the nonprofit Decentralized Autonomous Organization “Teia DAO LLC's”, under Non-Profit Entities Act 2020 (P.L. 2021-29) (18 MIRC, Ch. 2), located at PO Box 852, Long Island Rd Majuro in the Republic of the Marshall Islands. + +By accessing this website you accept these terms and conditions. Also, by using our platform, you accept to abide by our [Code of Conduct](https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions). Do not continue to use the Teia marketplace if you do not agree to take all of the terms and conditions stated on this page. + +To use our Service, you must use a third-party wallet that allows you to engage in transactions on blockchains. When you use Teia Marketplace, you acknowledge that you are subject to the terms of service and privacy policy of these wallet extensions. + +The following terminology applies to these Terms and Conditions, Privacy Policy, and all Agreements: "User", "You" and "Your" refers to you, the person logs on this website and compliant with the Company's terms and conditions. "The DAO", "Ourselves", "We", "Our" and "Us", refers to our Company. "Party", "Parties", or "Us", refers to both the Client and ourselves. Any use of the above terminology or other words in the singular, plural, capitalization, and/or he/she or they, are taken as interchangeable and therefore as referring to the same. + +## **1\. TEIA Marketplace** + +**1.1** Teia marketplace provides a peer-to-peer web3 platform where users can interact with each other by transacting, selling, purchasing, and showcasing blockchain assets. 01.2.-Teia is not a broker, financial institution, or creditor, and it strictly provides a platform for trading Crypto Assets. TEIA Marketplace's focus is solely on facilitating transactions between buyers and sellers of Crypto Assets. TEIA is not a party to any agreement between buyers and sellers of Crypto Assets on the TEIA Marketplace, and any such agreement is solely between the buyer and the seller. + +**1.2** TEIA does not have ownership, custody, or control of digital crypto assets created by our users. Creators of these digital assets are solely responsible for their content or functionality. TEIA is not responsible for any issues that may arise from the use or ownership of digital crypto assets including but not limited to their authenticity, quality, or legality. + +## 2\. License + +**2.1** Teia’s name is part of the intellectual property of Teia Markeptlac and its owned by TEIA or its affiliates or licensors and are protected by intellectual property laws. You may not copy, imitate, or use any TEIA’s name without our prior written permission for each use. + +**2.2** All rights to the user content made available through Teia marketplace are retained by the user, with the exception of those required to enable the operation of our marketplace. By making your content available on Teia, you grant us a license to access, use, host, cache, store, copy, transmit, display, publish, and distribute in any media or distribution method, but solely as necessary to operate and provide services on our platform. + +You acknowledge and agree that these license rights are royalty-free, transferable, sub-licensable, worldwide, and irrevocable for the entire duration of your User Content being offered on the Teia platform. + +**2.3** The content linked to or associated with any digital crypto assets displayed on TEIA Marketplace, are the property of their respective owners and are protected by intellectual property laws. You may not copy, imitate, or use any third-party intellectual property without the permission of the applicable intellectual property rights holder. Any reference to any products, services, processes, or other information by name, trademark, manufacturer, supplier, or otherwise, does not constitute or imply endorsement, sponsorship, or recommendation by TEIA Marketplace. + +**2.4 Software License:** Teia is developed under MIT/Open Source license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Sofware, and to permit persons to whom the Sofware is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE + +## 3\. Assumption of Risks and Content Liability + +· By using our marketplace you acknowledge and accept the volatility of blockchain assets price. TEIA does not guarantee that purchasers of Crypto Assets will not suffer losses. + +· You are solely responsible for determining any applicable taxes for your crypto assets transactions. Neither TEIA nor any other party associated with TEIA will be responsible for determining their applicable taxes. + +· Crypto Assets are not stored, sent, or received by the TEIA Marketplace. This is because Crypto Assets only exist based on ownership records maintained on the supporting blockchain, and any transfers of Crypto Assets occur solely on the blockchain and not on the TEIA Marketplace. + +· In order to access and use Teia Marketplace, you are responsible for providing all the necessary software and equipment required for connectivity and usage of the service. + +·There are various risks involved in using cryptocurrencies, including but not limited to risks of software, hardware, internet connectivity, or unauthorized access by third parties to assets stored on your wallet. You acknowledge that TEIA will not be responsible for any communication failures, errors, or delays experienced while using Crypto Assets, regardless of the cause. + +· **Purchasing user-generated content has risks, including but not limited to counterfeit assets, mislabeled assets, assets with metadata decay vulnerabilities, assets with bugs, and assets that may become non-transferable. TEIA reserves the right to hide assets affected by these or other issues. Inaccessibility of assets on TEIA is not grounds for a claim against TEIA.** + +· By using our Marketplace, you acknowledge and agree that you assume all risk and responsibility for any breach of license terms by purchasers of content sold on the platform. You waive and release Teia Marketplace from any claims, damages, or liability arising from such breaches or misuse. + +## 4\. User's Rights and Obligations + +· You agree not to engage in any activities that violate any laws, contracts, intellectual property rights, or other third-party rights. You acknowledge that you are solely responsible for your actions and behavior while accessing or using the platform. + +· You guarantee to abide by our Code of Conduct ([https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions](https://github.com/teia-community/teia-docs/wiki/Core-Values-Code-of-Conduct-Terms-and-Conditions)). · By purchasing a Crypto Asset through Teia Marketplace, you agree that you have conducted sufficient research and have gathered all necessary information to make an informed decision about its purchase. + +· You acknowledge and agree that you are solely responsible for verifying the authenticity, legitimacy, and identity of any Crypto Asset you purchase on Teia Marketplace. Furthermore, you understand and accept that Teia Marketplace makes no guarantees or promises regarding the identity, legitimacy, or authenticity of any Crypto Asset available on the platform. + +· When creating content through Teia Marketplace, you warrant that you own all legal rights or enough title in the intellectual property rights or you are legally authorized by the intellectual property owner of such asset. + +· The creator of each crypto asset determines the license terms applied to it. It's the users’ sole responsibility to review and understand the relevant licensing terms before making a purchase. + +## 5\. Removal of Content From TEIA + +If you find any content on our platform that is offensive for any reason, you are free to contact and inform us at any moment. We will consider requests to hide content that doesn’t follow any of our Policies, but we are not obligated to respond to you directly. + +## Disclaimer + +· We do not guarantee that the Teia marketplace will meet your requirements, be uninterrupted, timely, secure, or error-free, or that it will be accurate, reliable, complete, or safe. We take no responsibility for any losses, damages, or claims arising from any use of crypto assets, including user errors, server failure or data loss, corrupted wallet files, unauthorized access to applications, or any unauthorized third-party activities. + +· Teia DAO LLC is not responsible for damages sustained due to vulnerability or any kind of failure, abnormal behavior of software (e.g., wallet, smart contract), blockchains, or any other features of the platform or its content. + +· We may, at our sole discretion and without prior notice, terminate your access to the Teia Marketplace for any reason or no reason at all. You acknowledge and agree that we will not be liable or obligated to you in any way in the event of such termination, and you will not be entitled to a refund of any fees paid to us, to the fullest extent allowed by applicable law. + +· We may modify or update our Marketplace and these Terms of Service at our discretion and without prior notice to you. You agree that the platform may change, evolve or be updated over time and that we may add or remove features and make changes to any aspect of Teia’s Marketplace. + +## Content Warning** + +`The art on the Teia.art marketplace is user-created and some of it might not be suitable for all ages. If you are underaged, don’t use the platform without your legal guardians.` + +## Jurisdiction + +·These Terms shall be interpreted in accordance with the laws of the Republic of The Marshall Islands. + +·Any legal disputes that arise from or are related to these terms, including disputes regarding its validity, enforcement, modification, or termination, will be exclusively resolved in the ordinary courts of the Republic of The Marshall Islands \ No newline at end of file diff --git a/src/pages/codeofconduct/index.jsx b/src/pages/codeofconduct/index.jsx new file mode 100644 index 000000000..a4fa1ef5d --- /dev/null +++ b/src/pages/codeofconduct/index.jsx @@ -0,0 +1,26 @@ +import { useState } from 'react' +import { Page, Container } from '@atoms/layout' +import Markdown from 'markdown-to-jsx' + +export const CodeOfConduct = () => { + const [terms, setTerms] = useState('') + + const document = `src/lang/en/codeofconduct.md` + fetch(document) + .then((response) => response.text()) + .then((text) => { + setTerms(text) + }) + + return ( + + + {terms && ( + + {terms} + + )} + + + ) +} diff --git a/src/pages/codeofconduct/index.module.scss b/src/pages/codeofconduct/index.module.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/pages/corevalues/index.jsx b/src/pages/corevalues/index.jsx new file mode 100644 index 000000000..90ea0dd57 --- /dev/null +++ b/src/pages/corevalues/index.jsx @@ -0,0 +1,26 @@ +import { useState } from 'react' +import { Page, Container } from '@atoms/layout' +import Markdown from 'markdown-to-jsx' + +export const CoreValues = () => { + const [terms, setTerms] = useState('') + + const document = `src/lang/en/corevalues.md` + fetch(document) + .then((response) => response.text()) + .then((text) => { + setTerms(text) + }) + + return ( + + + {terms && ( + + {terms} + + )} + + + ) +} diff --git a/src/pages/corevalues/index.module.scss b/src/pages/corevalues/index.module.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/pages/dao/tabs/Parameters.jsx b/src/pages/dao/tabs/Parameters.jsx index 26d6d62e8..bbd49bb38 100644 --- a/src/pages/dao/tabs/Parameters.jsx +++ b/src/pages/dao/tabs/Parameters.jsx @@ -67,16 +67,16 @@ export default function DaoParameters() { {userAddress && ( <>
    -

    User information

    - +

    User Information

    +

    Your activities with the TEIA DAO is listed here.

    • Address: {}
    • {userCommunity &&
    • Representative for {userCommunity}.
    • }
    • - DAO token balance: {Math.round(userTokenBalance * 10) / 10} TEIA + DAO Token Balance: {Math.round(userTokenBalance * 10) / 10} TEIA
    • - Submited proposals:{' '} + Submitted Proposals:{' '} {Object.values(proposals).reduce( (acc, proposal) => acc + (proposal.issuer === userAddress ? 1 : 0), @@ -84,12 +84,12 @@ export default function DaoParameters() { )}
    • - Voted in {numberOfTimesVoted} proposal + Voted in {numberOfTimesVoted} Proposal {numberOfTimesVoted === 1 ? '' : 's'}.
    • {userCommunity && (
    • - Voted in {numberOfTimesVotedAsRepresentative} proposal + Voted in {numberOfTimesVotedAsRepresentative} Proposal {numberOfTimesVotedAsRepresentative === 1 ? '' : 's'} as community representative.
    • @@ -102,46 +102,67 @@ export default function DaoParameters() { )}
      -

      DAO information

      - +

      DAO Information

      +

      + Community-wide statistics and usage activities of the TEIA DAO. To + learn more about the the ideas and philosophies behind the DAO, visit + the{' '} + + official blog post + {' '} + after the DAO's first launch. For detailed information on governance + processes, check out the{' '} + + Governance on Teia Documentation + + . +

      • Members:{' '} - {daoMemberCount} + {daoMemberCount} (Click for List of Existing Members)
      • -
      • Total number of proposals: {Object.keys(proposals).length}
      • +
      • Total Number of Proposals: {Object.keys(proposals).length}
      • - Open proposals:{' '} + Open Proposals:{' '} {Object.values(proposals).reduce( (acc, proposal) => acc + (proposal.status.open ? 1 : 0), 0 )}
      • - Executed proposals:{' '} + Executed Proposals:{' '} {Object.values(proposals).reduce( (acc, proposal) => acc + (proposal.status.executed ? 1 : 0), 0 )}
      • - Rejected proposals:{' '} + Rejected Proposals:{' '} {Object.values(proposals).reduce( (acc, proposal) => acc + (proposal.status.rejected ? 1 : 0), 0 )}
      • - Cancelled proposals:{' '} + Cancelled Proposals:{' '} {Object.values(proposals).reduce( (acc, proposal) => acc + (proposal.status.cancelled ? 1 : 0), 0 )}
      • - Treasury balance: {Math.round(daoBalance)} tez and{' '} + Treasury Balance: {Math.round(daoBalance)} tez and{' '} {Math.round(daoTokenBalance * 10) / 10} TEIA tokens
      @@ -150,8 +171,16 @@ export default function DaoParameters() {
      -

      Community representatives

      - +

      Community Representatives

      +

      + Community Representatives are for voting members who are interested in + delegating their votes to other members of the community - people may + want to entrust their voting power to someone who is more active in + the DAO proposal process to represent them, for example. Otherwise, + the DAO defaults to direct participation based on the number of TEIA + tokens each wallet holds. +

      +

      For more information, read the

        {Object.entries(representatives).map( ([representative, community]) => ( @@ -172,36 +201,41 @@ export default function DaoParameters() {

        - Current DAO governance parameters + Current DAO Governance Parameters

        - +

        + How the current governance model works in terms of voting, timing, and + weighting of each vote. These parameters can change at any time - + however, to change these parameters it must be done so by the approval + of the DAO itself. +

        • - Vote method:{' '} + Vote Method:{' '} {gp.vote_method.linear ? 'linear weight' : 'quadratic weight'}
        • - Required quorum: {daoStorage.quorum / voteScaling} weighted votes + Required Quorum: {daoStorage.quorum / voteScaling} weighted votes
        • - Percentage for supermajority: {gp.supermajority}% positive votes + Percentage for Supermajority: {gp.supermajority}% positive votes
        • - Representatives vote share: {gp.representatives_share}% of the + Representatives Vote Share: {gp.representatives_share}% of the quorum
        • - Representative max vote share: {gp.representative_max_share}% of the + Representative Max Vote Share: {gp.representative_max_share}% of the quorum
        • -
        • Proposal voting period: {gp.vote_period} days
        • -
        • Proposal waiting period: {gp.wait_period} days
        • +
        • Proposal Voting Period: {gp.vote_period} Days
        • +
        • Proposal Waiting Period: {gp.wait_period} Days
        • - Number of tokens to escrow to submit a proposal:{' '} + Number of Tokens to Escrow to Submit a Proposal:{' '} {gp.escrow_amount / DAO_TOKEN_DECIMALS} TEIA tokens
        • - Minimum number of tokens required to vote a proposal:{' '} + Minimum Number of Tokens Required to Vote on a Proposal:{' '} {gp.min_amount / DAO_TOKEN_DECIMALS} TEIA tokens
        @@ -210,11 +244,16 @@ export default function DaoParameters() {
        -

        Smart contracts

        - +

        Smart Contracts

        +

        + The current set of smart contracts that keep the DAO running on a + technical level. These contracts may be replaced or updated on + occasion for adjustments or improvements, but can only be done through + the approval of the DAO's proposal process. +

        • - DAO governance:{' '} + DAO Governance:{' '}
        • @@ -238,6 +277,27 @@ export default function DaoParameters() {
        + + + +
        +

        Polls

        +

        + TEIA's polling system is a community tool that any TEIA member can use + for any purpose - it is often used for feature requests, testing + interest or getting feedback for ideas (artistic or technical), + measuring community sentiment around certain issues, or just for fun. +

        +

        + TEIA's polling system can be found{' '} + + here. + {' '} + (The DAO is typically reserved for issues that affect core + administration, budgeting, and existential issues that require the + full participation of the community itself.) +

        +
        ) } diff --git a/src/pages/faq/index.jsx b/src/pages/faq/index.jsx index a9228ebc3..d7a875090 100644 --- a/src/pages/faq/index.jsx +++ b/src/pages/faq/index.jsx @@ -28,7 +28,9 @@ export const FAQ = () => { return (
        -

        teia.art FAQ

        +

        + Getting Started with the TEIA Community +

          { - 'This feed show OBJKTs of your collectors and artists you collected from.' + 'This feed shows OBJKTs of your collectors and artists you collected from.' }

        diff --git a/src/pages/privacypolicy/index.jsx b/src/pages/privacypolicy/index.jsx new file mode 100644 index 000000000..1a511039e --- /dev/null +++ b/src/pages/privacypolicy/index.jsx @@ -0,0 +1,26 @@ +import { useState } from 'react' +import { Page, Container } from '@atoms/layout' +import Markdown from 'markdown-to-jsx' + +export const PrivacyPolicy = () => { + const [terms, setTerms] = useState('') + + const document = `src/lang/en/privacypolicy.md` + fetch(document) + .then((response) => response.text()) + .then((text) => { + setTerms(text) + }) + + return ( + + + {terms && ( + + {terms} + + )} + + + ) +} diff --git a/src/pages/privacypolicy/index.module.scss b/src/pages/privacypolicy/index.module.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/pages/terms/index.jsx b/src/pages/terms/index.jsx index 8e7a927d3..72a80e3fc 100644 --- a/src/pages/terms/index.jsx +++ b/src/pages/terms/index.jsx @@ -1,27 +1,16 @@ -import { useCallback, useEffect, useState } from 'react' +import { useState } from 'react' import { Page, Container } from '@atoms/layout' - import Markdown from 'markdown-to-jsx' -import useLanguage from '@hooks/use-language' export const Terms = () => { - // eslint-disable-next-line no-unused-vars - const { language } = useLanguage() const [terms, setTerms] = useState('') - const loadDocument = useCallback(() => { - const document = `/languages/documents/terms-${language}.md` - fetch(document) - .then((response) => response.text()) - .then((text) => { - setTerms(text) - // this.forceUpdate() - }) - }, [language]) - - useEffect(() => { - loadDocument() - }, [loadDocument]) + const document = `src/lang/en/terms.md` + fetch(document) + .then((response) => response.text()) + .then((text) => { + setTerms(text) + }) return ( From 4f4cdb7407100fc469a09863ffd0d4adb7887b24 Mon Sep 17 00:00:00 2001 From: ryangtanaka Date: Sun, 2 Feb 2025 10:22:58 -0800 Subject: [PATCH 10/13] polls and dao metadata update --- .../header/feed_toolbar/FeedToolbar.jsx | 15 ++- .../header/feed_toolbar/index.module.scss | 4 + src/components/header/main_menu/MainMenu.jsx | 2 +- src/pages/dao/tabs/Parameters.jsx | 51 +++++++--- src/pages/dao/tabs/TeiaDAOMetadataTzkt.jsx | 94 +++++++++++++++++++ src/pages/polls/TeiaPolls.jsx | 4 +- src/pages/polls/tabs/Polls.jsx | 25 ++++- 7 files changed, 173 insertions(+), 22 deletions(-) create mode 100644 src/pages/dao/tabs/TeiaDAOMetadataTzkt.jsx diff --git a/src/components/header/feed_toolbar/FeedToolbar.jsx b/src/components/header/feed_toolbar/FeedToolbar.jsx index 413314803..376b12090 100644 --- a/src/components/header/feed_toolbar/FeedToolbar.jsx +++ b/src/components/header/feed_toolbar/FeedToolbar.jsx @@ -28,7 +28,7 @@ const locationMap = new Map([ ['/feed/newobjkts', 'New OBJKTs'], ['/feed/friends*', 'Friends'], // separator - ['---fund_feeds', 'fund_feeds'], + ['---fund_feeds', 'Event Feeds'], ['/feed/art4artists', 'Art4Artists'], ['/feed/tez4pal', '🇵🇸 Tez4Pal'], ['/feed/morocco-quake-aid', '🇲🇦 Quake Aid'], @@ -38,7 +38,7 @@ const locationMap = new Map([ ['/feed/iran', '🇮🇷 Iran'], ['/feed/tezospride', '🏳️‍🌈 Tezospride'], // separator - ['---mime_feeds', 'mime_feeds'], + ['---mime_feeds', 'By Format'], ['/feed/image', 'Image'], ['/feed/video', 'Video'], ['/feed/audio', 'Audio'], @@ -64,7 +64,7 @@ export const FeedToolbar = ({ feeds_menu = false }) => { const feedLabel = [...locationMap.entries()].find(([key]) => location.pathname.startsWith(key.replace('*', '')) - )?.[1] || 'Sort' // Default to "Sort" if no match is found + )?.[1] || 'Sort Feed' // Default to "Sort" if no match is found const navigate = useNavigate() const walletAddress = useUserStore((st) => [st.address], shallow) @@ -86,7 +86,14 @@ export const FeedToolbar = ({ feeds_menu = false }) => {
        {[...locationMap.keys()].map((k) => { if (k.startsWith('-')) { - return + return ( + <> + + + {locationMap.get(k)} + + + ) } if (locationNeedSync.includes(k)) { return ( diff --git a/src/components/header/feed_toolbar/index.module.scss b/src/components/header/feed_toolbar/index.module.scss index af7251651..b8d4e9cb3 100644 --- a/src/components/header/feed_toolbar/index.module.scss +++ b/src/components/header/feed_toolbar/index.module.scss @@ -107,6 +107,10 @@ padding-bottom: 1em; } +.subtitle { + font-weight: bold; +} + .filters_container { display: flex; flex-direction: row; diff --git a/src/components/header/main_menu/MainMenu.jsx b/src/components/header/main_menu/MainMenu.jsx index 761e2e075..8d6da191d 100644 --- a/src/components/header/main_menu/MainMenu.jsx +++ b/src/components/header/main_menu/MainMenu.jsx @@ -90,7 +90,7 @@ export const MainMenu = () => { diff --git a/src/pages/dao/tabs/Parameters.jsx b/src/pages/dao/tabs/Parameters.jsx index bbd49bb38..21047a8a5 100644 --- a/src/pages/dao/tabs/Parameters.jsx +++ b/src/pages/dao/tabs/Parameters.jsx @@ -20,6 +20,7 @@ import { } from '@data/swr' import LoadingDaoMessage from '../LoadingDaoMessage' import styles from '@style' +import TeiaTokenMetadata from './TeiaDAOMetadataTzkt' export default function DaoParameters() { // Get all the required DAO information @@ -125,6 +126,11 @@ export default function DaoParameters() { .

        +

        + The information for the DAO is sourced from tzkt.io and + cross-referenced with TEIA's own indexer, both pulling from Tezos' + on-chain data. +

        • Members:{' '} @@ -166,6 +172,17 @@ export default function DaoParameters() { {Math.round(daoTokenBalance * 10) / 10} TEIA tokens
        +
        + +

        + + Convert XTZ to TEIA on Quipuswap (Decentralized Exchange) + +

        @@ -180,7 +197,18 @@ export default function DaoParameters() { the DAO defaults to direct participation based on the number of TEIA tokens each wallet holds.

        -

        For more information, read the

        +

        + For more information, read the{' '} + + Governance on Teia Documentation + {' '} + for more details. +

        +

        Currently Active Community Representatives

          {Object.entries(representatives).map( ([representative, community]) => ( @@ -257,22 +285,22 @@ export default function DaoParameters() {
        • - DAO token: + DAO Token:
        • - DAO treasury:{' '} + DAO Treasury:{' '}
        • - DAO guardians:{' '} + DAO Guardians:{' '}
        • - DAO administrator:{' '} + DAO Administrator:{' '}
        • - Community representatives:{' '} + Community Representatives:{' '}
        @@ -289,13 +317,10 @@ export default function DaoParameters() { measuring community sentiment around certain issues, or just for fun.

        - TEIA's polling system can be found{' '} - - here. - {' '} - (The DAO is typically reserved for issues that affect core - administration, budgeting, and existential issues that require the - full participation of the community itself.) + TEIA's polling system can be found here. (The DAO + is typically reserved for issues that affect core administration, + budgeting, and existential issues that require the full participation + of the community itself.)

      diff --git a/src/pages/dao/tabs/TeiaDAOMetadataTzkt.jsx b/src/pages/dao/tabs/TeiaDAOMetadataTzkt.jsx new file mode 100644 index 000000000..e1f0cee89 --- /dev/null +++ b/src/pages/dao/tabs/TeiaDAOMetadataTzkt.jsx @@ -0,0 +1,94 @@ +import React, { useState, useEffect } from 'react' +import axios from 'axios' + +const TeiaTokenMetadata = () => { + const [tokenData, setTokenData] = useState(null) + const [isLoading, setIsLoading] = useState(true) + const [error, setError] = useState(null) + + useEffect(() => { + const fetchTokenData = async () => { + try { + const response = await axios.get( + 'https://api.tzkt.io/v1/tokens?contract=KT1QrtA753MSv8VGxkDrKKyJniG5JtuHHbtV&tokenId=0' + ) + if (response.data && response.data.length > 0) { + setTokenData(response.data[0]) + } else { + setError('No token data found.') + } + } catch (error) { + setError('Failed to fetch token data.') + console.error('Error fetching token data:', error) + } finally { + setIsLoading(false) + } + } + + fetchTokenData() + }, []) + + if (isLoading) { + return

      Loading token data...

      + } + + if (error) { + return

      {error}

      + } + + if (!tokenData) { + return

      No token data available.

      + } + + return ( +
      +

      + Symbol: {tokenData.metadata.symbol} +

      +
      +

      + Token ID: {tokenData.tokenId} +

      +

      + Token Standard: {tokenData.standard} +

      +

      + Contract Alias: {tokenData.contract.alias} +

      +

      + Contract Address: {tokenData.contract.address} +

      +

      + First Minter Alias:{' '} + {tokenData.firstMinter?.alias || 'N/A'} +

      +

      + First Minter Address:{' '} + {tokenData.firstMinter?.address || 'N/A'} +

      +

      + Transfers Count: {tokenData.transfersCount} +

      +

      + Balances Count: {tokenData.balancesCount} +

      +

      + Holders Count: {tokenData.holdersCount} +

      +

      + Total Minted:{' '} + {(parseInt(tokenData.totalMinted) / 1000000).toFixed(2)} TEIA +

      +

      + Total Burned:{' '} + {(parseInt(tokenData.totalBurned) / 1000000).toFixed(2)} TEIA +

      +

      + Total Supply:{' '} + {(parseInt(tokenData.totalSupply) / 1000000).toFixed(2)} TEIA +

      +
      + ) +} + +export default TeiaTokenMetadata diff --git a/src/pages/polls/TeiaPolls.jsx b/src/pages/polls/TeiaPolls.jsx index 639e65a63..5e2a603bf 100644 --- a/src/pages/polls/TeiaPolls.jsx +++ b/src/pages/polls/TeiaPolls.jsx @@ -23,9 +23,9 @@ export default function TeiaPolls() { const [polls] = usePolls(pollsStorage) return ( - +
      -

      Teia community polls

      +

      Teia Community Polls

      {!polls ? ( diff --git a/src/pages/polls/tabs/Polls.jsx b/src/pages/polls/tabs/Polls.jsx index 8133af22d..5cb099669 100644 --- a/src/pages/polls/tabs/Polls.jsx +++ b/src/pages/polls/tabs/Polls.jsx @@ -48,8 +48,29 @@ export default function Polls() { return (
      -

      Teia polls

      - +

      Teia Polls

      +

      + TEIA's polling system is a community tool that any TEIA member can use + for any purpose - it is often used for feature requests, testing + interest or getting feedback for ideas (artistic or technical), + measuring community sentiment around certain issues, or just for fun. +

      +

      + To start or participate in a poll, the wallet sync'd must have a + non-zero amount of TEIA tokens, which is a Layer-2 token under the Tezos + (XTZ) chain. If you're interested in acquiring $TEIA, you can read the + guide here. +

      +

      + + Convert XTZ to TEIA on Quipuswap (Decentralized Exchange) + +

      + { disabled={progress} />
      -
      +
      +

      Price

      { disabled={progress} />
      -
      - -
    +

    From 96db059c27bbade5320bc18a24f6d910f75e776a Mon Sep 17 00:00:00 2001 From: ryangtanaka Date: Sun, 2 Feb 2025 12:51:54 -0800 Subject: [PATCH 13/13] core team multisig link --- src/pages/dao/tabs/Parameters.jsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/pages/dao/tabs/Parameters.jsx b/src/pages/dao/tabs/Parameters.jsx index ff6071e34..bda16df6c 100644 --- a/src/pages/dao/tabs/Parameters.jsx +++ b/src/pages/dao/tabs/Parameters.jsx @@ -174,6 +174,7 @@ export default function DaoParameters() { tez and {Math.round(daoTokenBalance * 10) / 10} TEIA tokens +

    @@ -270,6 +271,20 @@ export default function DaoParameters() { {gp.min_amount / DAO_TOKEN_DECIMALS} TEIA tokens +

    + Currently TEIA's marketplace contract is handled by{' '} + + TEIA's Core Team Multisig + {' '} + for teia.art's day-to-day activities. TEIA token holders are legally + defined as "operating members" of TEIA DAO LLC, which gives them + ultimate authority over the actions and functions of the community, + expressed through the voting and proposal mechanisms of the DAO + itself. +