Skip to content

Commit

Permalink
a bunch of misc stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
codekansas committed Nov 5, 2024
1 parent e07bd48 commit 7fb133f
Show file tree
Hide file tree
Showing 17 changed files with 764 additions and 235 deletions.
6 changes: 3 additions & 3 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import OrderSuccess from "./components/pages/OrderSuccess";
import OrdersPage from "./components/pages/Orders";
import PrivacyPolicy from "./components/pages/PrivacyPolicy";
import ResearchPage from "./components/pages/ResearchPage";
import TerminalPage from "./components/pages/Terminal";
import Terminal from "./components/pages/Terminal";
import TermsOfService from "./components/pages/TermsOfService";

const App = () => {
Expand Down Expand Up @@ -83,8 +83,8 @@ const App = () => {
<Route path="/success" element={<OrderSuccess />} />
<Route path="/orders" element={<OrdersPage />} />

<Route path="/terminal" element={<TerminalPage />} />
<Route path="/terminal/:id" element={<TerminalPage />} />
<Route path="/terminal" element={<Terminal />} />
<Route path="/terminal/:id" element={<Terminal />} />

<Route path="/404" element={<NotFound />} />
<Route path="*" element={<NotFoundRedirect />} />
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/components/listing/ListingArtifactRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ const ListingArtifactRenderer = ({ artifact }: Props) => {
);
case "tgz":
return (
<div className="w-full h-full bg-gray-3 flex items-center justify-center">
<div className="w-full h-full bg-gray-3 flex flex-col items-center justify-center gap-2">
<Link
to={`/file/${artifact.artifact_id}`}
className="p-4 hover:bg-gray-4 rounded-lg transition-colors"
>
<FaFileArchive className="w-16 h-16" />
</Link>
<div className="text-center">
<div className="font-medium">{artifact.name}</div>
<div className="text-sm text-gray-600">
Created {new Date(artifact.timestamp * 1000).toLocaleDateString()}
</div>
</div>
</div>
);
default:
Expand Down
14 changes: 6 additions & 8 deletions frontend/src/components/modals/DeleteRobotModal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useCallback, useState } from "react";
import { FaTrash } from "react-icons/fa";

import { SingleRobotResponse } from "@/components/terminal/types";
import { Button } from "@/components/ui/button";
import {
Dialog,
Expand All @@ -9,16 +11,12 @@ import {
DialogTitle,
} from "@/components/ui/dialog";
import { ApiError } from "@/lib/types/api";
import { Trash2 } from "lucide-react";

interface DeleteRobotModalProps {
isOpen: boolean;
onClose: () => void;
onDelete: (robotId: string) => Promise<void>;
robot: {
id: string;
name: string;
};
robot: SingleRobotResponse;
}

export function DeleteRobotModal({
Expand All @@ -34,7 +32,7 @@ export function DeleteRobotModal({
setIsLoading(true);
setError(null);
try {
await onDelete(robot.id);
await onDelete(robot.robot_id);
onClose();
} catch (error) {
console.error("Error deleting robot:", error);
Expand All @@ -51,7 +49,7 @@ export function DeleteRobotModal({
} finally {
setIsLoading(false);
}
}, [robot.id, onDelete, onClose]);
}, [robot.robot_id, onDelete, onClose]);

return (
<Dialog open={isOpen} onOpenChange={onClose}>
Expand Down Expand Up @@ -84,7 +82,7 @@ export function DeleteRobotModal({
disabled={isLoading}
variant="destructive"
>
<Trash2 className="mr-2 h-4 w-4" />
<FaTrash className="mr-2 h-4 w-4" />
<span>{isLoading ? "Deleting..." : "Delete Robot"}</span>
</Button>
</div>
Expand Down
168 changes: 147 additions & 21 deletions frontend/src/components/pages/FileBrowser.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { useEffect, useState } from "react";
import { FaFileDownload, FaHome } from "react-icons/fa";
import {
FaCheck,
FaFileDownload,
FaList,
FaPen,
FaTimes,
} from "react-icons/fa";
import { useNavigate, useParams } from "react-router-dom";

import FileRenderer from "@/components/files/FileRenderer";
import FileTreeViewer from "@/components/files/FileTreeViewer";
import { parseTar } from "@/components/files/Tarfile";
import Spinner from "@/components/ui/Spinner";
import { Tooltip } from "@/components/ui/ToolTip";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { components } from "@/gen/api";
import { humanReadableError, useAlertQueue } from "@/hooks/useAlertQueue";
import { useAuthentication } from "@/hooks/useAuth";
Expand All @@ -29,6 +38,15 @@ const FileBrowser = () => {
const auth = useAuthentication();
const { addErrorAlert } = useAlertQueue();
const navigate = useNavigate();
const [isEditing, setIsEditing] = useState(false);
const [editedName, setEditedName] = useState("");
const [editedDescription, setEditedDescription] = useState("");
const [isSaving, setIsSaving] = useState(false);

if (!artifactId) {
navigate("/");
return null;
}

useEffect(() => {
(async () => {
Expand Down Expand Up @@ -70,6 +88,13 @@ const FileBrowser = () => {
})();
}, [artifactId, auth.client, addErrorAlert, artifact]);

useEffect(() => {
if (artifact) {
setEditedName(artifact.name);
setEditedDescription(artifact.description || "");
}
}, [artifact]);

const handleDownload = () => {
if (!artifact?.urls.large) {
addErrorAlert("Artifact URL not available.");
Expand All @@ -88,6 +113,36 @@ const FileBrowser = () => {
setSelectedFile(file);
};

const handleSaveEdit = async () => {
setIsSaving(true);
try {
const { error } = await auth.client.PUT("/artifacts/edit/{artifact_id}", {
params: {
query: { id: artifactId },
},
body: {
name: editedName,
description: editedDescription,
},
});

if (error) {
addErrorAlert(error);
} else {
setArtifact((prev) =>
prev
? { ...prev, name: editedName, description: editedDescription }
: null,
);
setIsEditing(false);
}
} catch (err) {
addErrorAlert(humanReadableError(err));
} finally {
setIsSaving(false);
}
};

if (loading) {
return (
<div className="flex justify-center items-center pt-8">
Expand All @@ -98,26 +153,97 @@ const FileBrowser = () => {

return artifact?.urls.large ? (
<div className="max-w-6xl mx-auto px-4 py-8">
<h1 className="text-3xl font-bold mb-4">{artifact.name}</h1>
<p className="text-gray-600 mb-4">{artifact.description}</p>
<div className="flex flex-col sm:flex-row sm:space-x-4 space-y-2 sm:space-y-0 mb-6">
<Button
onClick={() => navigate("/")}
variant="secondary"
className="w-full sm:w-auto"
>
<FaHome className="mr-2" />
Home
</Button>
<Button
onClick={handleDownload}
variant="secondary"
disabled={!artifact.urls?.large}
className="w-full sm:w-auto"
>
<FaFileDownload className="mr-2" />
Download
</Button>
<div className="flex items-center justify-between mb-2 min-w-0">
{isEditing ? (
<div className="flex-1 mr-4 min-w-0">
<Input
value={editedName}
onChange={(e) => setEditedName(e.target.value)}
className="text-2xl font-semibold mb-2 break-all w-full"
/>
<Textarea
value={editedDescription}
onChange={(e) => setEditedDescription(e.target.value)}
className="w-full break-words"
placeholder="Description (optional)"
/>
</div>
) : (
<div className="flex-1 min-w-0 overflow-hidden">
<h1 className="text-2xl font-semibold break-all overflow-wrap-anywhere">
{artifact.name}
</h1>
{artifact.description && (
<p className="text-sm text-gray-600 mt-2 break-words whitespace-pre-wrap overflow-wrap-anywhere">
{artifact.description}
</p>
)}
</div>
)}
<div className="flex space-x-2 pl-4">
{isEditing ? (
<>
<Tooltip content="Save Changes" position="bottom">
<Button
onClick={handleSaveEdit}
variant="ghost"
size="icon"
className="h-8 w-8"
disabled={isSaving}
>
{isSaving ? <Spinner className="h-4 w-4" /> : <FaCheck />}
</Button>
</Tooltip>
<Tooltip content="Cancel" position="bottom">
<Button
onClick={() => setIsEditing(false)}
variant="ghost"
size="icon"
className="h-8 w-8"
disabled={isSaving}
>
<FaTimes />
</Button>
</Tooltip>
</>
) : (
<>
<Tooltip content="Edit Artifact Details" position="bottom">
<Button
onClick={() => setIsEditing(true)}
variant="ghost"
size="icon"
className="h-8 w-8"
>
<FaPen />
</Button>
</Tooltip>
<Tooltip content="View Listing" position="bottom">
<Button
onClick={() =>
navigate(`/item/${artifact.username}/${artifact.slug}`)
}
variant="ghost"
size="icon"
className="h-8 w-8"
>
<FaList />
</Button>
</Tooltip>
<Tooltip content="Download Files" position="bottom">
<Button
onClick={handleDownload}
variant="ghost"
size="icon"
className="h-8 w-8"
disabled={!artifact.urls?.large}
>
<FaFileDownload />
</Button>
</Tooltip>
</>
)}
</div>
</div>
<div className="flex flex-col lg:flex-row lg:space-x-4">
<div className="w-full lg:w-1/3 mb-4 lg:mb-0">
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/pages/Orders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { paths } from "@/gen/api";
import { useAuthentication } from "@/hooks/useAuth";

type OrderWithProduct =
paths["/orders/user-orders-with-products"]["get"]["responses"][200]["content"]["application/json"][0];
paths["/orders/user-orders-with-products"]["get"]["responses"][200]["content"]["application/json"][number];

const OrdersPage: React.FC = () => {
const navigate = useNavigate();
Expand Down
Loading

0 comments on commit 7fb133f

Please sign in to comment.