Skip to content

Commit

Permalink
Merge pull request #183 from olivorocksrotated/pin-notes
Browse files Browse the repository at this point in the history
Pin notes
  • Loading branch information
nbaglivo authored Sep 15, 2023
2 parents 3d48908 + 025fd99 commit 2e71ed6
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 31 deletions.
36 changes: 28 additions & 8 deletions src/app/(user)/components/workspace/components/context/context.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Note } from '@prisma/client';
import Link from 'next/link';
import { ParsedUrlQuery } from 'querystring';

import { FilterOption } from '@/lib/notes/get-notes-by-tags';

Expand All @@ -16,6 +17,19 @@ function buildQueryWithoutTag(tag: string, selectedTagsFilter?: string[]) {

type ContextProps = { tags: string[], notes: Note[], selectedTagsFilter?: string[], selectedOperator?: FilterOption };

const fixedTags = [{ label: 'Pinned', value: 'pinned' }];
const fixedTagValues = fixedTags.map(({ value }) => value);

function TagLink({ tag, query, isSelected }: { tag: string, query: ParsedUrlQuery, isSelected: boolean }) {
return (
<Link href={{ query }}
className={`cursor-pointer rounded border border-neutral-800 bg-neutral-950 px-2 ${isSelected ? ' border-red-400 ' : ''}`}
>
{tag}
</Link>
);
}

export default function Context({ tags, notes, selectedTagsFilter, selectedOperator }: ContextProps) {
const isSelected = (tag: string) => selectedTagsFilter?.includes(tag) || false;

Expand All @@ -28,18 +42,24 @@ export default function Context({ tags, notes, selectedTagsFilter, selectedOpera
};
}

function renderTag({ value, label }: { value: string, label: string }) {
return <TagLink key={value} tag={label} query={buildQuery(value)} isSelected={isSelected(value)} />;
}

const dynamicTags = tags.reduce((tagsSofar, tag) => {
if (!fixedTagValues.includes(tag)) {
return [...tagsSofar, { value: tag, label: tag }];
}

return tagsSofar;
}, [] as { value: string, label: string }[]);

return (
<div className="overflow-scroll">
<div className="my-5 flex flex-wrap gap-4">
<FilterSelect defaultValue={selectedOperator}></FilterSelect>
{tags.map((tag) => (
<Link href={{ query: buildQuery(tag) }}
className={`cursor-pointer rounded border border-neutral-800 bg-neutral-950 px-2 ${isSelected(tag) ? ' border-red-400 ' : ''}`}
key={tag}
>
{tag}
</Link>
))}
{fixedTags.map(renderTag)}
{dynamicTags.map(renderTag)}
</div>

{notes.map(({ text, id }) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,70 @@
import { Selection } from '@tiptap/pm/state';
import { AiOutlinePushpin } from 'react-icons/ai';
import { MdEditNote } from 'react-icons/md';
import { useZact } from 'zact/client';

import { createNoteAction } from '@/lib/notes/create';

import { getTagsFromFragment } from '../editor-utils';


export default function Options({ selection }: { selection?: Selection }) {
const { mutate: createNote } = useZact(createNoteAction);

function createNoteFromSelection(extraTags?: string[]) {
if (selection) {
const tags = getTagsFromFragment(selection.content().content);
createNote({ text: JSON.stringify({ ...selection.content(), type: 'doc' }), tags: [...tags, ...extraTags || []] });
}
}

const options = [
{ label: 'Unresolved note',
action: () => {
if (selection) {
const tags = getTagsFromFragment(selection.content().content);
createNote({ text: JSON.stringify({ ...selection.content(), type: 'doc' }), tags });
{
icon: null,
sectionTitle: '',
actions: [
{
label: 'Pin',
icon: <AiOutlinePushpin className="mr-2" />,
exec: () => createNoteFromSelection(['pinned'])
}
} },
/* eslint-disable no-empty-function */
{ label: 'Task', action: () => {} },
/* eslint-disable no-empty-function */
{ label: 'Commitment', action: () => {} },
/* eslint-disable no-empty-function */
{ label: 'Feedback', action: () => {} }
]
},
{
icon: null,
sectionTitle: 'Turn into',
actions: [
{
label: 'Standalone Note',
icon: <MdEditNote className="mr-2" />,
exec: () => createNoteFromSelection()
}
]
}
];

return (
<div className="p-2">
<div className="text-sm text-neutral-200">Turn into</div>
<div className="h-64 w-64 rounded border border-neutral-950 bg-neutral-900 shadow-xl">
<div className="flex flex-col items-start">
{options.map((option) => (
<button onClick={option.action}
className="w-full rounded px-2 py-1 text-left outline-none hover:bg-neutral-500 focus:bg-neutral-500"
type="button"
key={option.label}
>
{option.label}
</button>
))}
{
options.map((option, index) => (
<div key={option.sectionTitle} className={`flex w-full flex-col ${index > 0 ? ' my-1 border-t border-neutral-950 ' : ''}`}>
<div className="mx-1 mt-2 text-sm text-neutral-400">{option.sectionTitle}</div>
{option.actions.map((action) => (
<div key={action.label}
className="mx-1 rounded-sm hover:bg-neutral-700 focus:bg-neutral-700"
>
<button onClick={action.exec}
className="mx-2 flex items-center px-2 py-1 outline-none"
type="button"
>
{action.icon} {action.label}
</button>
</div>
))}
</div>
))
}
</div>
</div>
);
Expand Down

1 comment on commit 2e71ed6

@vercel
Copy link

@vercel vercel bot commented on 2e71ed6 Sep 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.