Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calendar v0 #88

Merged
merged 56 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
770d3ed
testing out full calendar
Jul 19, 2023
f8041a7
get events as function working
Aug 2, 2023
32354f9
remove incorrect prop
Aug 2, 2023
0c2c052
preview for to calendar graphql query
Aug 3, 2023
3a1f958
styling full calendar
Aug 7, 2023
179f8a0
fix calendar height
Aug 7, 2023
4c3fed7
styling artists on calendar slot
Aug 7, 2023
728d11e
update event time so it works with datetime-local input
Aug 7, 2023
b1dd229
update getallartists query and set initial values for artist field
Aug 7, 2023
6179b7e
add extra artist fields
Aug 7, 2023
ffbf200
add reload/loading button
Aug 7, 2023
32a2e0e
add animation pause state to tailwind
Aug 7, 2023
644b669
fix typescript error
Aug 7, 2023
b5f529f
remove packge lock from accidental npm install
Aug 7, 2023
f8ac091
update yarn checksums
Aug 7, 2023
bfae306
testing preview on vercel
Aug 8, 2023
afaaf3f
preview now working on graphql
Aug 8, 2023
b876a39
adding status colours, status input and link to show on contentful
Aug 8, 2023
44eb830
creating calendar show now working
Aug 9, 2023
cb39352
fix day view
Aug 9, 2023
39a92dc
fix disabled options on multi select when limit is set to 1
Aug 9, 2023
61f5707
editing events now working
Aug 15, 2023
9856585
remove footer from calendar page
Aug 15, 2023
874f8cb
fix issue with editing shows when certain fields don't exist
Aug 16, 2023
c2257a9
make loading icon rotate at least once
Aug 16, 2023
4c5b016
fix day header format
Aug 16, 2023
c367abf
add dropdown menu for new event and images
Aug 17, 2023
993c3b9
dont update internal name
Aug 25, 2023
a613067
add automated email template
Aug 25, 2023
9613cfb
adjust title and id so naming is inline with full calendar
Aug 29, 2023
3e7f494
returned new event from contentful now parsed correctly for full cale…
Sep 4, 2023
535927d
new submission form with initial fields filled out from contentful
Sep 13, 2023
c27a853
fix type errors
Sep 13, 2023
ca60b40
upcoming show emails api working + extended day on calendar to 2am
Sep 27, 2023
94fdab6
add datepicker
Sep 28, 2023
de09a07
improve calendar on mobile
Sep 28, 2023
9ba04b9
tighten up toolbar on desktop
Sep 28, 2023
af840e6
reduce margin on mobile
Sep 28, 2023
845bb9f
set default view to day on mobile
Sep 28, 2023
5747929
move crud updates on contentful to client
Oct 16, 2023
35d8463
remove json
Oct 16, 2023
66b3f95
remove unncessary functions
Oct 16, 2023
4fd4bc8
add keyboard shortcuts
Oct 16, 2023
880ae8a
dont respond to key handlers if show dialog is open
Oct 18, 2023
51a1beb
edit button added to all pages with corresponding id on contentful (#77)
antiantivirus Oct 18, 2023
6855c17
Supabase auth (#82)
antiantivirus Oct 23, 2023
cef342d
adjust url for calendar to remove footer and chatroom button
Oct 23, 2023
c08cb7d
prepare calendar for read-only mode
Oct 23, 2023
3d9f2ef
revert show submission and api route
Nov 1, 2023
a0cc916
add radix ui radio group
Nov 1, 2023
cee7bfb
transpile radix ui package to solve deployment issue
Nov 1, 2023
81aaaf9
transpile all radix ui packages
Nov 1, 2023
001d843
fix contentful show link
Nov 1, 2023
efe8236
merge master and resolve conflicts
Nov 2, 2023
ac66325
remove border from date input on desktop
Nov 2, 2023
cae77c1
fix conflicts with main
Nov 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,7 @@ yarn-error.log*
/public/sitemap.xml

# google sheets secret
secrets.json
secrets.json

#react email
.react-email
22 changes: 22 additions & 0 deletions components/edit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Link from "next/link";
import { AiOutlineEdit } from "react-icons/ai";
import { usePathname } from "next/navigation";
import { useUser } from "@supabase/auth-helpers-react";

export default function Edit({ id }: { id?: string }) {
const pathname = usePathname();
const user = useUser();

if (id && user)
return (
<Link
className={`absolute ${
pathname == "/" ? "mt-[58px] sm:mt-28 " : "mt-4"
} right-6 rounded-full border border-black bg-white p-3 shadow-md z-10`}
href={`https://app.contentful.com/spaces/${process.env.NEXT_PUBLIC_CONTENTFUL_SPACE_ID}/entries/${id}`}
target="_blank"
>
<AiOutlineEdit size={20} aria-label="Edit" />
</Link>
);
}
10 changes: 7 additions & 3 deletions components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ import { Arrow } from "../icons/arrow";
import Mixcloud from "../icons/mixcloud";
import Soundcloud from "../icons/soundcloud";
import Telegram from "../icons/telegram";
import { useUser } from "@supabase/auth-helpers-react";
import SignOut from "./signOut";

export default function Footer() {
const handleGoToTop = () =>
window?.scroll({ top: 0, left: 0, behavior: "smooth" });

const user = useUser();

return (
<footer className="bg-black text-white">
<div className="px-4 md:px-8 py-10 md:py-20">
Expand Down Expand Up @@ -48,17 +52,17 @@ export default function Footer() {
<div className="px-4 md:px-8 border-t border-white py-4 md:py-6">
<div className="grid lg:grid-cols-3 gap-8 lg:gap-12 text-small font-medium">
{/* Spacer */}
<div className="hidden lg:block" />
{user ? <SignOut /> : <div className="hidden lg:block" />}

<div className="flex justify-center">
<button
onClick={handleGoToTop}
className="focus:outline-none inline-flex items-center space-x-4"
>
<span>Go up</span>
<span className="mt-1">
{/* <span className="mt-1">
<Arrow className="-rotate-90" size={24} />
</span>
</span> */}
</button>
</div>

Expand Down
157 changes: 63 additions & 94 deletions components/formFields/extraArtists.tsx
Original file line number Diff line number Diff line change
@@ -1,109 +1,78 @@
import { useState } from "react";
import ImageUploadField from "./imageUploadField";
import { Close } from "../../icons/menu";
// import SingleLineField from "./singleLineField";
// import TextareaField from "./textareaField";
import TextareaField from "./textareaField";
import CheckboxField from "./checkboxField";
import InputField from "./inputField";
import { useFormikContext, FieldArray } from "formik";
import { SubmissionFormValues } from "../../types/shared";

export default function ExtraArtists({
setExtraArtistsParent,
}: {
setExtraArtistsParent: (arg: Array<{ name: string; bio: string }>) => void;
}) {
const [artistExists, setArtistExists] = useState<boolean>(true);
const [extraArtists, setExtraArtists] = useState([{ name: "", bio: "" }]);

const handleFormChange = (event, index) => {
let data = [...extraArtists];
data[index][event.target.name] = event.target.value;
setExtraArtists(data);
setExtraArtistsParent(data);
};

const addArtistFields = () => {
let object = {
name: "",
bio: "",
};

setExtraArtists([...extraArtists, object]);
};

const removeArtistFields = (index) => {
let data = [...extraArtists];
data.splice(index, 1);
setExtraArtists(data);
};
export default function ExtraArtists() {
const { values } = useFormikContext<SubmissionFormValues>();

return (
<div>
<div>
<input
type="checkbox"
id="artistExists"
name="artistExists"
onChange={(e) => setArtistExists(!e.target.checked)}
className="h-6 w-6 rounded-full border-2 border-black text-black focus:ring-black"
/>
<label htmlFor="artistExists" className="checkbox-label">
Can&apos;t find artist/guest in the dropdown
</label>
</div>
<CheckboxField
name="hasExtraArtists"
label="Can't find your artist/guest/collective in the dropdown?"
size="small"
/>

{!artistExists && (
<fieldset className="mt-8 mb-8">
<legend className="mb-6">Artist/guest info</legend>
{extraArtists.map((form, index) => {
return (
<div
className="mb-8 border border-black p-8 relative"
key={index}
>
{values.hasExtraArtists && (
<fieldset className=" mb-8">
<legend className="mb-6">Additional artist(s)</legend>
<FieldArray
name="extraArtists"
render={(arrayHelpers) => (
<div>
{values.extraArtists &&
values.extraArtists.map((extraArtist, index) => (
<div
className="mb-8 border border-black p-8 relative"
key={"extraArtist" + index}
>
{index > 0 && (
<button
className="float-right"
onClick={() => arrayHelpers.remove(index)}
type="button"
>
<Close size={24} />
</button>
)}
<InputField
name={`extraArtists.${index}.name`}
type="text"
label="Name"
required
/>
<InputField
name={`extraArtists.${index}.pronouns`}
type="text"
label="Pronouns"
/>
<TextareaField
name={`extraArtists.${index}.bio`}
rows={4}
label="Bio"
/>
<ImageUploadField
label="Image"
required
name={`extraArtists.${index}.image`}
/>
</div>
))}
<button
className="float-right"
onClick={() => removeArtistFields(index)}
className="underline"
onClick={() => arrayHelpers.push("")}
type="button"
>
<Close size={24} />
Add another artist/guest
</button>
<div className="mb-6 mt-6">
<label htmlFor="name">Name</label>
<input
type="text"
name="name"
className="pill-input"
onChange={(event) => handleFormChange(event, index)}
value={form.name}
required
/>
</div>
<div className="mb-6">
<label htmlFor="bio">Bio</label>
<textarea
rows={4}
name="bio"
className="pill-input"
onChange={(event) => handleFormChange(event, index)}
value={form.bio}
required
/>
</div>
<ImageUploadField
label="Guest image"
name="guestImage"
// required={true}
/>
</div>
);
})}
<button className="underline" onClick={addArtistFields}>
Add another artist/guest
</button>

{/* <SingleLineField
label="Instagram @ handle(s)"
name="instagram"
required={true}
type="text"
/> */}
)}
/>
</fieldset>
)}
</div>
Expand Down
8 changes: 5 additions & 3 deletions components/formFields/multiSelectField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@ export default function MultiSelectField({
description,
options,
limit,
value,
...props
}: {
label: string;
description?: string;
name: string;
required?: boolean;
options: Array<{ value: string; label: string }>;
value?: Array<{ value: string; label: string; email?: [string] }>;
options: Array<{ value: string; label: string; email?: [string] }>;
limit?: number;
}) {
const [ariaFocusMessage, setAriaFocusMessage] = useState("");
const [selectedOptions, SetSelectedOptions] = useState([]);
const [selectedOptions, SetSelectedOptions] = useState(value ? value : []);
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [field, meta, helpers] = useField(props);
const { setFieldValue } = useFormikContext();
Expand Down Expand Up @@ -55,7 +57,7 @@ export default function MultiSelectField({
className="basic-multi-select pill-input mb-2 p-2"
value={selectedOptions}
onChange={(o) => onSetSelectedOptions(o)}
isOptionDisabled={() => selectedOptions.length >= limit}
isOptionDisabled={() => selectedOptions.length >= limit && limit != 1}
name={props.name}
id={props.name}
classNamePrefix="select"
Expand Down
4 changes: 4 additions & 0 deletions components/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { Fragment } from "react";
import Alert from "./alert";
import Edit from "./edit";

export default function Layout({
className,
children,
preview,
pageId,
}: {
children: React.ReactNode;
preview?: boolean;
className?: string;
pageId?: string;
}) {
return (
<Fragment>
{preview && <Alert />}
<Edit id={pageId} />
<main className={className}>{children}</main>
</Fragment>
);
Expand Down
24 changes: 17 additions & 7 deletions components/navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { Menu } from "../icons/menu";
import MessageSquare from "../icons/message-square";
import Search from "../icons/search";
import NavigationLink from "./navigationLink";
import { useUser } from "@supabase/auth-helpers-react";
import { AiOutlineCalendar } from "react-icons/ai";

export default function Navigation() {
const [isOpen, isOpenSet] = useState(false);
Expand All @@ -21,6 +23,8 @@ export default function Navigation() {
window.open("/chat", "refugechatwindow", chatOptions);
}, []);

const user = useUser();

return (
<Dialog.Root open={isOpen} onOpenChange={(open) => isOpenSet(open)}>
<nav className="text-black">
Expand Down Expand Up @@ -144,13 +148,19 @@ export default function Navigation() {
</a>
</li>
<li>
<a
target="_blank"
rel="noopener noreferrer"
href={INSTAGRAM_URL}
>
<Instagram />
</a>
{user ? (
<Link href="/admin/calendar">
<AiOutlineCalendar />
</Link>
) : (
<a
target="_blank"
rel="noopener noreferrer"
href={INSTAGRAM_URL}
>
<Instagram />
</a>
)}
</li>
</ul>
</li>
Expand Down
32 changes: 0 additions & 32 deletions components/showSubmissionStep1.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,38 +25,6 @@ export default function ShowSubmissionStep1() {
</label>
</RadioGroup.Item>
</RadioGroup.Root>
{/* <div className="flex">
<div className="w-1/2">
<Field
type="radio"
id="live"
name="showType"
value="live"
className="peer hidden"
/>
<label
htmlFor="live"
className="block cursor-pointer select-none pill-input rounded-tr-none rounded-br-none py-3 text-center peer-checked:bg-orange peer-checked:font-bold"
>
Live
</label>
</div>
<div className="w-1/2">
<Field
type="radio"
id="preRecord"
name="showType"
value="preRecord"
className="peer hidden"
/>
<label
htmlFor="preRecord"
className="block cursor-pointer select-none pill-input rounded-tl-none rounded-bl-none py-3 text-center peer-checked:bg-blue peer-checked:font-bold"
>
Pre-recorded
</label>
</div>
</div> */}
<ErrorMessage className="text-red" component="span" name="showType" />
</fieldset>
</div>
Expand Down
16 changes: 16 additions & 0 deletions components/signOut.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
import { useRouter } from "next/router";

export default function SignOut() {
const supabase = createClientComponentClient();
const router = useRouter();
const handleSignOut = async () => {
await supabase.auth.signOut();
router.reload();
};
return (
<button className="text-left grow-0" onClick={handleSignOut}>
Sign out
</button>
);
}
Loading