Skip to content

Commit

Permalink
️💋🦾 ↝ [SSM-62 SSG-88]: Attempting to implement a new design for uploa…
Browse files Browse the repository at this point in the history
…d schema
  • Loading branch information
Gizmotronn committed Dec 28, 2024
1 parent 56d122e commit 73ec49e
Showing 1 changed file with 126 additions and 110 deletions.
236 changes: 126 additions & 110 deletions components/Projects/(classifications)/FreeForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@ import { useEffect, useRef, useState } from 'react';
import useSound from 'use-sound';
import Webcam from "react-webcam";
import { useSupabaseClient, useSession } from '@supabase/auth-helpers-react';
import { useActivePlanet } from '@/context/ActivePlanet';

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Upload, ChevronRight, Camera } from "lucide-react";
import { Upload, ChevronRight, Camera } from 'lucide-react';

const STRUCTURE_OPTIONS: Record<string, string[]> = { // Update to add `dataSources...` identifiers
const STRUCTURE_OPTIONS: Record<string, string[]> = {
Telescope: ["Sunspot", "Asteroid", "Planet", "Star", "Nebula", "Crater"],
LIDAR: ["Planetary Cloud", "Neutrino", "Earth Cloud", "Surface"],
Zoodex: ["Bird", "Penguin", "Owl", "Other Animal"],
};

const FreeformUploadData = () => {
const supabase = useSupabaseClient();
const supabase = useSupabaseClient();
const session = useSession();
const { activePlanet } = useActivePlanet();

const webcamRef = useRef<Webcam>(null);
const [loadingContent, setLoadingContent] = useState(false);
Expand All @@ -33,6 +32,7 @@ const FreeformUploadData = () => {
const [anomalyType, setAnomalyType] = useState<string>("");
const [structure, setStructure] = useState<string>("");
const [uploads, setUploads] = useState<string[]>([]);
const [showForm, setShowForm] = useState(false);

const takeScreenshot = async () => {
if (loadingContent || buttonPressed) return;
Expand All @@ -46,26 +46,31 @@ const FreeformUploadData = () => {
if (imageSrc) {
const resizedImage = await resizeImage(imageSrc);
setCaptureImage(resizedImage);
setShowForm(true);
}
};

const uploadImage = async (e: React.ChangeEvent<HTMLInputElement>) => {
if (loadingContent || buttonPressed) return;
setButtonPressed(true);
setTimeout(() => {
setButtonPressed(false);
setLoadingContent(true);
}, 200);

const files = e.target.files;
if (files && files.length > 0) {
const file = files[0];
const reader = new FileReader();
reader.onloadend = () => {
setCaptureImage(reader.result as string);
};
reader.readAsDataURL(file);
}
if (loadingContent || buttonPressed) return;
setButtonPressed(true);
setLoadingContent(true);

const files = e.target.files;
if (files && files.length > 0) {
const file = files[0];
const reader = new FileReader();
reader.onloadend = async () => {
const resizedImage = await resizeImage(reader.result as string);
setCaptureImage(resizedImage);
setShowForm(true);
setButtonPressed(false);
setLoadingContent(false);
};
reader.readAsDataURL(file);
} else {
setButtonPressed(false);
setLoadingContent(false);
}
};

const handleSubmitClassification = async (event: React.FormEvent) => {
Expand Down Expand Up @@ -110,7 +115,6 @@ const FreeformUploadData = () => {
.insert({
content: comment || null,
author: session?.user?.id,
location: activePlanet?.id,
source: 'freeform',
file_url: imageUrl ? imageUrl : null,
configuration: classificationConfiguration,
Expand All @@ -120,103 +124,114 @@ const FreeformUploadData = () => {
console.error('Supabase error:', error.message);
} else {
console.log('Classification added successfully', data);
// Reset form and go back to camera view
setShowForm(false);
setCaptureImage(null);
setComment("");
setCloudName("");
setLocation("");
setAnomalyType("");
setStructure("");
}
} catch (err) {
console.error('Unexpected error during classification insert:', err);
}
};

return (
<div className="bg-[#2C4F64] flex items-center justify-center p-4">
<div className="w-full max-w-md bg-[#FF695D] rounded-3xl p-8 shadow-lg">
<form onSubmit={handleSubmitClassification} className="space-y-4">
<Input
type="text"
placeholder="Name of data point/content/post"
value={cloudName}
onChange={(e) => setCloudName(e.target.value)}
className="bg-white text-[#2C4F64] placeholder:text-[#2C4F64]/70"
/>
<Input
type="text"
placeholder="Location"
value={location}
onChange={(e) => setLocation(e.target.value)}
className="bg-white text-[#2C4F64] placeholder:text-[#2C4F64]/70"
/>
<textarea
placeholder="Add additional comments (optional)"
value={comment}
onChange={(e) => setComment(e.target.value)}
className="bg-white text-[#2C4F64] placeholder:text-[#2C4F64]/70 p-2 rounded-md w-full h-32"
/>
<div className="grid grid-cols-1 gap-4">
<Label htmlFor="anomalyType" className="text-white">Structure/Project group</Label>
<select
id="anomalyType"
value={anomalyType}
onChange={(e) => setAnomalyType(e.target.value)}
className="bg-white text-[#2C4F64] rounded p-2"
>
<option value="" disabled>Select Structure</option>
{Object.keys(STRUCTURE_OPTIONS).map((structure) => (
<option key={structure} value={structure}>{structure}</option>
))}
</select>
</div>
<div className="grid grid-cols-1 gap-4">
<Label htmlFor="structure" className="text-white">Anomaly</Label>
<select
id="structure"
value={structure}
onChange={(e) => setStructure(e.target.value)}
className="bg-white text-[#2C4F64] rounded p-2"
disabled={!anomalyType}
>
<option value="" disabled>Select anomaly/entity type</option>
{anomalyType && STRUCTURE_OPTIONS[anomalyType].map((struct) => (
<option key={struct} value={struct}>{struct}</option>
))}
</select>
</div>
<div className="bg-[#5FCBC3] rounded-lg p-4 aspect-square mb-4">
{captureImage ? (
<img src={captureImage} alt="Captured" className="w-full h-full object-cover rounded" />
) : (
<div className="w-full h-full flex items-center justify-center bg-[#2C4F64] text-white">
<Webcam
ref={webcamRef}
forceScreenshotSourceSize={true}
screenshotFormat="image/jpeg"
videoConstraints={{ facingMode: "environment" }}
className="w-full h-full object-cover"
/>
</div>
)}
</div>
<div className="grid grid-cols-2 gap-4 mb-4">
<Button onClick={takeScreenshot} className="bg-[#2C4F64] text-white hover:bg-[#1E3D4F]">
Capture
</Button>
<Label htmlFor="file-upload" className="w-full flex justify-center">
<Button type="button" className="w-full bg-[#2C4F64] text-white hover:bg-[#1E3D4F]">
<Upload className="mr-2 h-4 w-4" /> Upload
<div className="bg-[#2C4F64] flex items-center justify-center w-full h-screen">
<div className="w-full h-full bg-[#FF695D] p-4 md:p-8">
{!showForm ? (
<div className="space-y-4">
<div className="bg-[#5FCBC3] rounded-lg p-4 h-[calc(100%-80px)] mb-4">
<Webcam
ref={webcamRef}
forceScreenshotSourceSize={true}
screenshotFormat="image/jpeg"
videoConstraints={{ facingMode: "environment" }}
className="w-full h-full object-cover"
/>
</div>
<div className="grid grid-cols-2 gap-4">
<Button onClick={takeScreenshot} className="bg-[#2C4F64] text-white hover:bg-[#1E3D4F]">
<Camera className="mr-2 h-4 w-4" /> Capture
</Button>
</Label>
<Label htmlFor="file-upload" className="w-full">
<Button type="button" className="w-full bg-[#2C4F64] text-white hover:bg-[#1E3D4F]">
<Upload className="mr-2 h-4 w-4" /> Upload
</Button>
</Label>
<Input
id="file-upload"
type="file"
accept="image/*"
onChange={uploadImage}
className="hidden"
/>
</div>
</div>
) : (
<form onSubmit={handleSubmitClassification} className="space-y-4 h-full flex flex-col">
<div className="bg-[#5FCBC3] rounded-lg p-4 h-40 mb-4">
{captureImage && (
<img src={captureImage} alt="Captured" className="w-full h-full object-cover rounded" />
)}
</div>
<Input
id="file-upload"
type="file"
accept="image/*"
onChange={uploadImage}
className="hidden"
type="text"
placeholder="Name of data point/content/post"
value={cloudName}
onChange={(e) => setCloudName(e.target.value)}
className="bg-white text-[#2C4F64] placeholder:text-[#2C4F64]/70"
/>
</div>

<Button type="submit" className="w-full bg-[#2C4F64] text-white hover:bg-[#1E3D4F]">
<ChevronRight className="mr-2 h-4 w-4" />
Submit
</Button>
</form>
<Input
type="text"
placeholder="Location"
value={location}
onChange={(e) => setLocation(e.target.value)}
className="bg-white text-[#2C4F64] placeholder:text-[#2C4F64]/70"
/>
<div className="grid grid-cols-1 gap-4">
<Label htmlFor="anomalyType" className="text-white">Structure/Project group</Label>
<select
id="anomalyType"
value={anomalyType}
onChange={(e) => setAnomalyType(e.target.value)}
className="bg-white text-[#2C4F64] rounded p-2"
>
<option value="" disabled>Select Structure</option>
{Object.keys(STRUCTURE_OPTIONS).map((structure) => (
<option key={structure} value={structure}>{structure}</option>
))}
</select>
</div>
<div className="grid grid-cols-1 gap-4">
<Label htmlFor="structure" className="text-white">Anomaly</Label>
<select
id="structure"
value={structure}
onChange={(e) => setStructure(e.target.value)}
className="bg-white text-[#2C4F64] rounded p-2"
disabled={!anomalyType}
>
<option value="" disabled>Select anomaly/entity type</option>
{anomalyType && STRUCTURE_OPTIONS[anomalyType].map((struct) => (
<option key={struct} value={struct}>{struct}</option>
))}
</select>
</div>
<textarea
placeholder="Add additional comments (optional)"
value={comment}
onChange={(e) => setComment(e.target.value)}
className="bg-white text-[#2C4F64] placeholder:text-[#2C4F64]/70 p-2 rounded-md w-full flex-grow"
/>
<Button type="submit" className="w-full bg-[#2C4F64] text-white hover:bg-[#1E3D4F]">
<ChevronRight className="mr-2 h-4 w-4" />
Submit
</Button>
</form>
)}
</div>
</div>
);
Expand Down Expand Up @@ -248,4 +263,5 @@ function convertBase64ToFile(base64Str: string, filename: string): Promise<File>
return fetch(base64Str)
.then((res) => res.arrayBuffer())
.then((buf) => new File([buf], filename, { type: 'image/jpeg' }));
};
};

0 comments on commit 73ec49e

Please sign in to comment.