-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
π₯πͺ β Finished boilerplate of planet/anomaly profile index
Users can now navigate to `/planets/{$planetID}` to see information relating to their planet, including datasets, articles, a sandbox, basic stats/info, a gallery, and a generator. Generator: Signal-K/sytizen#18 Right now it's just the same generator script, but eventually it will take in the fields like radius from the table the page itself is generated from. We'll update the frontend fields to use a UI based on the <Card /> component we've designed for the Profile pages. users will be able to edit these fields and create a fork of the anomaly in its dataset sandbox for use in their own projects, and this can be part of the "XP" demo for "citizen science points" to mimic the behaviour of the reputation erc20 token: Now that staking has been re-added, time to close #18 Signal-K/sytizen#16 Profile pages Signal-K/sytizen#13 Signal-K/sytizen#6 -> Generator & staking Signal-K/sytizen#1 -> sandbox & generator Signal-K/Unity-Demo#28 Signal-K/Unity-Demo#5 Signal-K/starsailors#4 -> user input on anomalies Signal-K/Silfur#26 Signal-K/Silfur#25 -> Some small changes with the Thirdweb module behaviour, still yet to commence full re-integration now though Signal-K/Silfur#24 Signal-K/Silfur#22 -> Replacing "mint" FOR NOW with just a "claim" button that sends the planet to your supabase table inventory (array/foreign key in 'profiles' table Signal-K/Silfur#21 Signal-K/Silfur#12 -> Keep an eye on this, but for now this is deprecated Signal-K/Silfur#3 -> Again keep an eye on the original card game contract, but until we commence the full re-integration of the smart contracts, this is not needed Signal-K/Silfur#30 -> This is working a treat Signal-K/Silfur#29 -> Now need to add true threaded comments & integrate it with sandbox items Full notes available here: https://www.notion.so/skinetics/February-Flow-Planets-8c864b66147c447f82136772336e9bc6?pvs=4#09b8260b2360412683ef5935309fd011
- Loading branch information
1 parent
5ce4247
commit ab6b6db
Showing
21 changed files
with
610 additions
and
238 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { useSupabaseClient, useSession } from "@supabase/auth-helpers-react"; | ||
|
||
import { useState } from "react"; | ||
|
||
import { ClimbingBoxLoader } from "react-spinners"; | ||
|
||
export default function PlanetCoverImage ( { url, editable, onChange } ) { | ||
const supabase = useSupabaseClient(); | ||
const session = useSession(); // Users who "own" a dataset will be able to edit the datapoint. However, persistent & permanent history will be retained. Datasets CAN be forked separately/with articles/refs | ||
|
||
const [isUploading, setIsUploading] = useState(false); | ||
|
||
async function updateCover (e) { | ||
const file = e.target.files?.[0]; | ||
if (file) { | ||
setIsUploading(true); | ||
const fileName = session?.user?.id + '_Planet_cover_' + Date.now(); // Include the planet name (from pages/planets/planet.tsx) | ||
const { data, error } = await supabase.storage | ||
.from('covers') // Should be changed to a planets/dataset>point buckets | ||
.upload(fileName, file) | ||
|
||
if (error) throw error; | ||
if (data) { | ||
const url = process.env.NEXT_PUBLIC_SUPABASE_URL + '/storage/v1/object/public/covers/' + data.path; | ||
supabase.from('planets') | ||
.update({ cover: url, }) | ||
.eq('id', session?.user?.id) // Should be set to the equivalent of `planet?.id` | ||
.then(({ data, error }) => { | ||
if (error) throw error; | ||
if (data && onChange) { onChange(); }; | ||
}); | ||
setIsUploading(false); | ||
} | ||
} | ||
} | ||
|
||
return ( | ||
<div className="h-60 overflow-hidden flex justify-center items-center relative"> | ||
<div><img src={url} alt="Planet's cover image"/></div> | ||
{/*{isUploading && ( // Until the upload function goes to the correct bucket and refs the correct object, this should not be visible/interactable | ||
<div className="absolute inset-0 bg-white bg-opacity-80% flex items-center z-10"><div className="inline-block mx-auto"><ClimbingBoxLoader /></div></div> | ||
)} | ||
{editable && ( | ||
<div className="items-center cursor-pointer absolute right-0 bottom-0 m-2"><label className="flex items-center gap-2 bg-white py-1 px-2 rounded-md shadow-md shadow-black cursor-pointer"> | ||
<input type='file' onChange={updateCover} className='hidden' /> | ||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6"><path strokeLinecap="round" strokeLinejoin="round" d="M6.827 6.175A2.31 2.31 0 015.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 00-1.134-.175 2.31 2.31 0 01-1.64-1.055l-.822-1.316a2.192 2.192 0 00-1.736-1.039 48.774 48.774 0 00-5.232 0 2.192 2.192 0 00-1.736 1.039l-.821 1.316z" /><path strokeLinecap="round" strokeLinejoin="round" d="M16.5 12.75a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0zM18.75 10.5h.008v.008h-.008V10.5z" /></svg>Change cover image</label> | ||
</div> | ||
)}*/} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import React, { useState, useEffect } from "react"; | ||
|
||
import { Database } from "../../utils/database.types"; | ||
import { useSupabaseClient } from "@supabase/auth-helpers-react"; | ||
|
||
type Planets = Database['public']['Tables']['planets']['Row']; | ||
|
||
export default function PlanetAvatar ({ uid, url, size, /*onUpload*/ }: { | ||
uid: string, | ||
url: Planets['avatar_url'], | ||
size: number, | ||
}) { | ||
let width = 'w-12'; | ||
const [uploading, setUploading] = useState(false); | ||
|
||
const supabase = useSupabaseClient<Database>(); | ||
const [avatarUrl, setAvatarUrl] = useState<Planets['avatar_url']>(null); | ||
|
||
useEffect(() => { | ||
if (url) downloadImage(url); | ||
}, [url]); | ||
|
||
async function downloadImage (path: string) { | ||
try { | ||
const { data, error } = await supabase.storage.from('avatars').download(path); | ||
if (error) { throw error; }; | ||
const url = URL.createObjectURL(data); | ||
setAvatarUrl(url); | ||
} catch (error) { | ||
console.log('Error download avatar: ', error); | ||
}; | ||
}; | ||
|
||
const uploadAvatar: React.ChangeEventHandler<HTMLInputElement> = async (event) => { // Keep this function disabled until we've set up a differentiation between the upload behaviour (and backend structure) of profile avatars & planet/datapoint avatars | ||
try { | ||
setUploading(true); | ||
if (!event.target.files || event.target.files.length === 0) { // If there is no file selected | ||
throw new Error('You must select an image to upload'); | ||
}; | ||
|
||
const file = event.target.files[0]; | ||
const fileExt = file.name.split('.').pop(); | ||
const fileName = `${uid}.${fileExt}`; | ||
const filePath = `${fileName}`; | ||
let { error: uploadError } = await supabase.storage | ||
.from('avatars') | ||
.upload(filePath, file, { upsert: true }) | ||
if (uploadError) { | ||
throw uploadError; | ||
}; | ||
|
||
//onUpload(filePath); | ||
} catch (error) { | ||
alert('Error uploading avatar, check console'); | ||
console.log(error); | ||
} finally { | ||
setUploading(false); | ||
} | ||
} | ||
|
||
return ( | ||
<div className="${width} rounded-full overflow-hidden"> | ||
{avatarUrl ? ( | ||
<img | ||
src={avatarUrl} | ||
alt='Avatar' | ||
className="avatar image" | ||
style={{ height: size, width: size }} | ||
/> | ||
) : ( | ||
<div className="avatar no-image" style={{ height: size, width: size }} /> | ||
)} | ||
{/* | ||
<div style={{ width: size }}> | ||
<label className="button primary block" htmlFor='single'> | ||
{uploading ? 'Uploading ...': 'Upload'} | ||
</label> | ||
<input | ||
style={{ | ||
visibility: 'hidden', | ||
position: 'absolute', | ||
}} | ||
type='file' | ||
id='single' | ||
accept='image/*' | ||
onChange={uploadAvatar} | ||
disabled={uploading} // Disabled once upload button/process clicked/initiated | ||
/> | ||
</div> | ||
*/} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import Link from "next/link"; | ||
|
||
export default function PlanetTabs ({ planetId, activeTab }) { | ||
const tabClasses = 'flex gap-1 px-4 py-1 items-center border-b-4 border-b-white'; | ||
const activeTabClasses = 'flex gap-1 px-4 py-1 items-center border-socialBlue border-b-4 text-socialBlue font-bold'; | ||
|
||
return ( | ||
<div className="mt-6 md:mt-10 flex gap-0"> | ||
<Link href={`/planets/${planetId}/`} className={activeTab === 'planet' ? activeTabClasses : tabClasses}> | ||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6"> | ||
<path strokeLinecap="round" strokeLinejoin="round" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" /> | ||
</svg> | ||
<span className="hidden sm:block">Bio</span> | ||
</Link> | ||
<Link href={`/planets/${planetId}/data`} className={activeTab === 'data' ? activeTabClasses : tabClasses}> | ||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6"> | ||
<path strokeLinecap="round" strokeLinejoin="round" d="M21 7.5l-2.25-1.313M21 7.5v2.25m0-2.25l-2.25 1.313M3 7.5l2.25-1.313M3 7.5l2.25 1.313M3 7.5v2.25m9 3l2.25-1.313M12 12.75l-2.25-1.313M12 12.75V15m0 6.75l2.25-1.313M12 21.75V19.5m0 2.25l-2.25-1.313m0-16.875L12 2.25l2.25 1.313M21 14.25v2.25l-2.25 1.313m-13.5 0L3 16.5v-2.25" /> | ||
</svg> | ||
<span className="hidden sm:block">Datasets</span> | ||
</Link> | ||
<Link href={`/planets/${planetId}/refs`} className={activeTab === 'refs' ? activeTabClasses : tabClasses}> {/* Posts that mention/use the planetId */} | ||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6"> | ||
<path strokeLinecap="round" strokeLinejoin="round" d="M9.568 3H5.25A2.25 2.25 0 003 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 005.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 009.568 3z" /> | ||
<path strokeLinecap="round" strokeLinejoin="round" d="M6 6h.008v.008H6V6z" /> | ||
</svg> | ||
<span className="hidden sm:block">Article Refs</span> | ||
</Link> | ||
<Link href={`/planets/${planetId}/sandbox`} className={activeTab === 'sandbox' ? activeTabClasses : tabClasses}> | ||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6"> | ||
<path strokeLinecap="round" strokeLinejoin="round" d="M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714c0 .597.237 1.17.659 1.591L19.8 15.3M14.25 3.104c.251.023.501.05.75.082M19.8 15.3l-1.57.393A9.065 9.065 0 0112 15a9.065 9.065 0 00-6.23-.693L5 14.5m14.8.8l1.402 1.402c1.232 1.232.65 3.318-1.067 3.611A48.309 48.309 0 0112 21c-2.773 0-5.491-.235-8.135-.687-1.718-.293-2.3-2.379-1.067-3.61L5 14.5" /> | ||
</svg> | ||
<span className="hidden sm:block">Sandbox</span> | ||
</Link> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.