Skip to content

Commit

Permalink
feat: clean up profile page and summary table
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamesb committed Feb 24, 2024
1 parent 7ec86d2 commit 804d562
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 118 deletions.
4 changes: 4 additions & 0 deletions packages/client/src/components/AccountDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { logout } from "../lib/login";
import { useNavigate } from "react-router-dom";
import { z } from "zod";
import { UserModel } from "shared/src/schemas/user";
import { SettingsModal } from "./SettingsModal";

interface AccountDropdownProps {
user: z.infer<typeof UserModel>;
Expand Down Expand Up @@ -52,6 +53,9 @@ export const AccountDropdown = (props: AccountDropdownProps) => {
>
View Profile
</MenuItem>
<MenuItem>
<SettingsModal>API Key</SettingsModal>
</MenuItem>
<MenuItem onClick={handleLogout}>Logout</MenuItem>
</Menu>
</div>
Expand Down
29 changes: 15 additions & 14 deletions packages/client/src/components/AdminPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const AdminPage = () => {

// Fetch data immediately and then set up the interval
fetchData();
const interval = setInterval(fetchData, 2000);
const interval = setInterval(fetchData, 5000);

// Clear interval on component unmount
return () => clearInterval(interval);
Expand Down Expand Up @@ -59,13 +59,8 @@ export const AdminPage = () => {
<span className="font-semibold">Username</span>
</TableCell>
<TableCell>
<span className="font-semibold">Created</span>
<span className="font-semibold">Created At</span>
</TableCell>
{
// <TableCell>
// <span className="font-semibold">Status</span>
// </TableCell>
}
<TableCell>
<span className="font-semibold">Tasks</span>
</TableCell>
Expand All @@ -82,7 +77,9 @@ export const AdminPage = () => {
<TableCell component="th" scope="row">
{pipeline.username}
</TableCell>
<TableCell>{dayjs(pipeline.createdAt).fromNow()}</TableCell>
<TableCell>
{dayjs(pipeline.createdAt).format("YY-MM-DD HH:mm:ss")}
</TableCell>
{
//<TableCell>{pipeline.status}</TableCell>
}
Expand Down Expand Up @@ -118,7 +115,15 @@ export const AdminPage = () => {
<TableRow key={task.id}>
<TableCell>{task.name}</TableCell>
<TableCell>
{dayjs(task.createdAt).fromNow()}
{
// mins since pipeline created
"+" +
dayjs(task.createdAt).diff(
dayjs(pipeline.createdAt),
"minute"
) +
" mins"
}
</TableCell>
<TableCell>
{idx === 0 ? pipeline.status : task.status}
Expand All @@ -129,11 +134,7 @@ export const AdminPage = () => {
{task.logs
.filter((x) => x.level !== "debug")
.map((log, idx) => (
<li key={idx}>
{dayjs(log.createdAt).fromNow()}
{" - "}
{log.log}
</li>
<li key={idx}>{log.log}</li>
))}
</ul>
)}
Expand Down
13 changes: 1 addition & 12 deletions packages/client/src/components/Homepage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,7 @@ export function Homepage(props: HomepageProps) {
</p>
<br></br>
<p></p>
<p>Changelog</p>
<ul className="list-disc list-inside">
<li>2024-01-21: Implement user profile and follower system.</li>
<li>2024-01-14: Add API.</li>
<li>2024-01-13: Add auth and server.</li>
<li>
2024-01-08: Integrate <a href="https://metaphor.systems/">metaphor</a>
.
</li>
</ul>
<br></br>
<p>Top Users:</p>
<p>Example Users:</p>
<ul className="list-disc list-inside">
{(users || []).map((user) => (
<li key={user.username}>
Expand Down
127 changes: 68 additions & 59 deletions packages/client/src/components/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,22 @@ import { RouterOutput, trpc } from "../lib/trpc";
import {
Avatar,
Button,
Collapse,
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
TextField,
Tooltip,
Typography,
} from "@mui/material";
import * as _ from "remeda";
import { OnboardingModal } from "./OnboardingModal";
import dayjs from "dayjs";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import ExpandLessIcon from "@mui/icons-material/ExpandLess";

interface ProfilePageProps {
auth: AuthInfo | undefined;
Expand Down Expand Up @@ -84,10 +89,7 @@ export function ProfilePage(props: ProfilePageProps) {
setProfileForUser(response);
});
}, [props.auth, usernameForProfile]);
const [apiKey, setApiKey] = React.useState<{
loading: boolean;
data?: string;
}>();

if (!props.auth?.authenticated) {
return (
<div>
Expand All @@ -100,7 +102,7 @@ export function ProfilePage(props: ProfilePageProps) {
summaries?.forEach((summary) => {
rows.push({
createdAt: summary.createdAt,
type: "Summary of User",
type: "Twitter Summary",
content: summary.content,
useForRecommendations: summary.useForRecommendations,
});
Expand Down Expand Up @@ -147,78 +149,85 @@ export function ProfilePage(props: ProfilePageProps) {
{isFollowing ? "Unfollow" : "Follow"}
</Button>
</Tooltip>
) : (
<>
{!apiKey ? (
<Button
disabled={!!apiKey}
variant="outlined"
onClick={async () => {
setApiKey({ loading: true });
const key = await trpc.getAPIKey.mutate();
if (!key) {
console.log("error getting api key");
return;
}
setApiKey({ loading: false, data: key });
}}
>
Get API Key
</Button>
) : (
<div>
Your API Key (
<OnboardingModal
shouldOpen
okayText="Ok"
title="API Key"
content="This is your API key. You can use it to upload custom recommendation inputs and get recommendations programmatically. It's like a password, so don't share it with anyone. It will only be shown once. If you lose your key or accidentally share it, create a new API key. You can paste this into the RemNote Incremental Everything plugin to interleave your recommendations with existing elements."
>
<a>What is this?</a>
</OnboardingModal>
): <pre>{apiKey.data}</pre>
</div>
)}
</>
)}
) : null}
</div>
<br></br>
<div>This table summarizes recommendation inputs.</div>
<br></br>
{
<OnboardingModal
shouldOpen
okayText="Ok"
title="TODO: DM James :)"
content="Didn't get around to implementing yet, please DM me and I can upload for you! Supports any text. Ideally summarized into max 2k tokens. Will eventually have full API support for create/update/delete recommendation inputs."
>
<Button variant="outlined">Upload Custom Input</Button>
</OnboardingModal>
}

<div className="flex items-center gap-2">
<TextField
id="outlined-basic"
label="Custom Query"
variant="outlined"
/>
<Button variant="contained">Search</Button>
</div>
<br></br>
<h3>Recommendation Inputs</h3>
<br></br>
<TableContainer component={Paper}>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Created At</TableCell>
<TableCell>Date</TableCell>
<TableCell>Type</TableCell>
<TableCell>Content</TableCell>
{viewingOwnProfile && <TableCell>Actions</TableCell>}
</TableRow>
</TableHead>
<TableBody>
{_.sortBy(rows, (x) => x.createdAt).map((row, idx) => (
<TableRow key={idx}>
<TableCell>{row.createdAt}</TableCell>
<TableCell>{row.type}</TableCell>
<TableCell>{row.content}</TableCell>
{viewingOwnProfile && <TableCell>Edit</TableCell>}
</TableRow>
<SummaryRow
key={idx}
row={row}
viewingOwnProfile={!!viewingOwnProfile}
/>
))}
</TableBody>
</Table>
</TableContainer>
</div>
);
}

interface SummaryRowProps {
row: TableRow;
viewingOwnProfile: boolean;
}

function SummaryRow(props: SummaryRowProps) {
const { row, viewingOwnProfile } = props;
const [expanded, setExpanded] = React.useState(false);
return (
<TableRow>
<TableCell>{dayjs(row.createdAt).format("YY-MM-DD")}</TableCell>
<TableCell>{row.type}</TableCell>
<TableCell>
<Collapse
className="relative max-w-[600px]"
collapsedSize={200}
in={expanded}
>
<Typography>{row.content}</Typography>
<div
className="absolute right-0 -bottom-2"
onClick={() => {
setExpanded(!expanded);
}}
>
{expanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</div>
</Collapse>
</TableCell>
{viewingOwnProfile && (
<TableCell>
<div>{/* <Button>Edit</Button> */}</div>
<div>
<Button onClick={() => {}} variant="contained">
Get Recommendations
</Button>
</div>
</TableCell>
)}
</TableRow>
);
}
77 changes: 77 additions & 0 deletions packages/client/src/components/SettingsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
} from "@mui/material";
import React from "react";
import { trpc } from "../lib/trpc";
import { OnboardingModal } from "./OnboardingModal";

interface SettingsModalProps {
children: React.ReactNode;
}

export function SettingsModal(props: SettingsModalProps) {
const [isOpen, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
const [apiKey, setApiKey] = React.useState<{
loading: boolean;
data?: string;
}>();
return (
<>
<span
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
handleOpen();
}}
>
{props.children}
</span>
<Dialog open={isOpen} onClose={handleClose}>
<DialogTitle>Settings</DialogTitle>
<DialogContent>
<div>
{!apiKey ? (
<Button
disabled={!!apiKey}
variant="outlined"
onClick={async () => {
setApiKey({ loading: true });
const key = await trpc.getAPIKey.mutate();
if (!key) {
console.log("error getting api key");
return;
}
setApiKey({ loading: false, data: key });
}}
>
Get API Key
</Button>
) : (
<div>
Your API Key (
<OnboardingModal
shouldOpen
okayText="Ok"
title="API Key"
content="This is your API key. You can use it to upload custom recommendation inputs and get recommendations programmatically. It's like a password, so don't share it with anyone. It will only be shown once. If you lose your key or accidentally share it, create a new API key. You can paste this into the RemNote Incremental Everything plugin to interleave your recommendations with existing elements."
>
<a>What is this?</a>
</OnboardingModal>
): <pre>{apiKey.data}</pre>
</div>
)}
</div>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Close</Button>
</DialogActions>
</Dialog>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- DropForeignKey
ALTER TABLE "PipelineTaskLog" DROP CONSTRAINT "PipelineTaskLog_pipelineTaskId_fkey";

-- AddForeignKey
ALTER TABLE "PipelineTaskLog" ADD CONSTRAINT "PipelineTaskLog_pipelineTaskId_fkey" FOREIGN KEY ("pipelineTaskId") REFERENCES "PipelineTask"("id") ON DELETE CASCADE ON UPDATE CASCADE;
2 changes: 1 addition & 1 deletion packages/server/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ model PipelineTaskLog {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
pipelineTaskId Int
pipelineTask PipelineTask @relation(fields: [pipelineTaskId], references: [id])
pipelineTask PipelineTask @relation(fields: [pipelineTaskId], references: [id], onDelete: Cascade)
level String
log String
}
Loading

0 comments on commit 804d562

Please sign in to comment.