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

Guild create button impl #146

Merged
merged 2 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 7 additions & 4 deletions src/components/AuthComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ export const Input = styled.input<{ error?: boolean }>`
&:focus {
border: 1px solid var(--primary);
}

// disabled styling
&:disabled {
background: var(--background-secondary-alt);
color: var(--text-disabled);
border: 1px solid var(--background-secondary-alt);
}
`;

export const Link = styled.button`
Expand Down Expand Up @@ -150,7 +157,3 @@ export const AuthSwitchPageLink = styled.button`
cursor: pointer;
}
`;

export const Divider = styled.span`
padding: 0 4px;
`;
5 changes: 5 additions & 0 deletions src/components/Divider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import styled from "styled-components";

export const Divider = styled.span`
padding: 0 4px;
`;
119 changes: 88 additions & 31 deletions src/components/modals/CreateServerModal.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { useModals } from "@mattjennings/react-modal-stack";
import { APIGuild, Routes } from "@spacebarchat/spacebar-api-types/v9";
import React from "react";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import styled from "styled-components";
import { useAppStore } from "../../stores/AppStore";
import { messageFromFieldError } from "../../utils/messageFromFieldError";
import {
Input,
InputErrorText,
InputLabel,
InputWrapper,
LabelWrapper,
} from "../AuthComponents";
import { Divider } from "../Divider";
import Icon from "../Icon";
import AddServerModal from "./AddServerModal";
import {
Expand All @@ -21,19 +32,6 @@ export const ModalHeader = styled.div`
padding: 24px 24px 0;
`;

const Input = styled.input`
border-radius: 8px;
padding: 10px;
margin-bottom: 10px;
border: none;
outline: none;
cursor: text;
font-size: 16px;
font-weight: 500;
color: var(--text);
background-color: var(--background-primary);
`;

const UploadIcon = styled.div`
padding-top: 4;
display: flex;
Expand Down Expand Up @@ -64,27 +62,22 @@ const FileInput = styled.div`
font-size: 0px;
`;

const NameInputContainer = styled.div`
const InputContainer = styled.div`
margin-top: 24px;
display: flex;
flex-direction: column;
`;

const FormLabel = styled.label`
margin-bottom: 8px;
font-size: 16px;
color: var(--text-header-secondary);
`;

type FormValues = {
serverName: string;
name: string;
};

function CreateServerModal() {
const app = useAppStore();
const { openModal, closeModal } = useModals();
const [selectedFile, setSelectedFile] = React.useState<File>();
const fileInputRef = React.useRef<HTMLInputElement>(null);
const navigate = useNavigate();

if (!open) {
return null;
Expand All @@ -93,20 +86,61 @@ function CreateServerModal() {
const {
register,
handleSubmit,
formState: { errors },
formState: { errors, isLoading },
setError,
setValue,
} = useForm<FormValues>();

React.useEffect(() => {
setValue("serverName", `${app.account?.username}'s guild`);
setValue("name", `${app.account?.username}'s guild`);
}, []);

const onIconChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (!event.target.files) return;
setSelectedFile(event.target.files[0]);
};

const onSubmit = handleSubmit((data) => {
app.rest
.post<Partial<APIGuild>, APIGuild>(Routes.guilds(), {
name: data.name,
})
.then((r) => {
navigate(`/channels/${r.id}`);
closeModal();
})
.catch((r) => {
if ("message" in r) {
if (r.errors) {
const t = messageFromFieldError(r.errors);
if (t) {
setError(t.field as keyof FormValues, {
type: "manual",
message: t.error,
});
} else {
setError("name", {
type: "manual",
message: r.message,
});
}
} else {
setError("name", {
type: "manual",
message: r.message,
});
}
} else {
// unknown error
console.error(r);
setError("name", {
type: "manual",
message: "Unknown Error",
});
}
});
});

return (
<ModalContainer>
<ModalWrapper>
Expand Down Expand Up @@ -148,8 +182,8 @@ function CreateServerModal() {
fill="none"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="m 39.88 78.32 c 4.0666 0 8.0467 -0.648 11.8282 -1.9066 l -0.9101 -2.7331 c -3.4906 1.1606 -7.1626 1.7597 -10.921 1.7597 v 2.88 m 17.4528 -4.3056 c 3.5539 -1.8749 6.7824 -4.3142 9.5645 -7.2115 l -2.0765 -1.993 c -2.569 2.6755 -5.5526 4.9277 -8.833 6.6586 l 1.345 2.5459 m 13.4208 -11.9434 c 2.2752 -3.3091 4.0061 -6.9638 5.1178 -10.8346 l -2.7677 -0.7949 c -1.0253 3.5712 -2.6237 6.9437 -4.7232 9.9965 l 2.3731 1.633 m 6.2899 -16.5917 c 0.1814 -1.4918 0.2765 -2.9981 0.2794 -4.5158 c 0 -2.5805 -0.2448 -5.063 -0.7344 -7.4966 l -2.8224 0.5674 c 0.4522 2.2464 0.6797 4.5389 0.6797 6.9264 c -0.0029 1.3997 -0.0893 2.7936 -0.2592 4.1702 l 2.8598 0.3514 m -2.1254 -17.8243 c -1.4198 -3.7642 -3.4416 -7.2662 -5.976 -10.3824 l -2.2349 1.8173 c 2.3386 2.8771 4.2048 6.1114 5.5181 9.5818 l 2.6928 -1.0166 m -10.1923 -14.783 c -3.0038 -2.6669 -6.4195 -4.8384 -10.1146 -6.4195 l -1.1347 2.6467 c 3.4099 1.4602 6.5635 3.4646 9.337 5.927 l 1.9123 -2.1542 m -15.7334 -8.3117 c -2.9146 -0.7286 -5.927 -1.1059 -8.9827 -1.1174 c -1.0886 0 -2.065 0.0374 -3.0499 0.1123 l 0.2218 2.8714 c 0.9101 -0.0691 1.8115 -0.1037 2.8224 -0.1037 c 2.8195 0.0086 5.5987 0.3571 8.2915 1.031 l 0.6998 -2.7936 m -17.9654 -0.0634 c -3.9197 0.9504 -7.6406 2.5286 -11.0362 4.6627 l 1.5322 2.4394 c 3.1363 -1.9699 6.5693 -3.4243 10.1837 -4.3027 l -0.6797 -2.7994 m -15.889 8.2886 c -3.0154 2.6554 -5.5872 5.7888 -7.6118 9.2506 l 2.4883 1.4515 c 1.8691 -3.2026 4.2451 -6.0883 7.0301 -8.5421 l -1.9037 -2.16 m -10.1952 14.6189 c -1.4371 3.7238 -2.2723 7.6723 -2.4595 11.7274 l 2.8771 0.1325 c 0.1728 -3.744 0.9446 -7.3843 2.2694 -10.823 l -2.687 -1.0368 m -2.2464 17.8618 c 0.4694 4.0205 1.5811 7.9027 3.2832 11.52 l 2.6064 -1.224 c -1.5696 -3.3408 -2.5978 -6.9235 -3.0298 -10.633 l -2.8598 0.3341 m 6.2698 16.7443 c 2.2694 3.3149 5.0573 6.2467 8.2541 8.6688 l 1.7453 -2.2925 c -2.952 -2.2464 -5.5267 -4.9565 -7.6205 -8.015 l -2.376 1.6272 m 13.4352 11.9923 c 3.5424 1.872 7.3699 3.168 11.3558 3.8246 l 0.4666 -2.8426 c -3.6806 -0.6048 -7.2086 -1.8 -10.4774 -3.528 l -1.3478 2.5459 m 17.3376 4.3229 c 0.0691 0 0.0691 0 0.1382 0 v -2.88 c -0.0634 0 -0.0634 0 -0.1267 0 l -0.0115 2.88"
fill="currentColor"
></path>
Expand All @@ -176,21 +210,44 @@ function CreateServerModal() {
<FileInput
role="button"
// disabled until I get the motiviation to not make it shit, I don't really want to use an invisible input
// onClick={() => fileInputRef.current?.click()}
onClick={() => fileInputRef.current?.click()}
></FileInput>
</IconContainer>
</UploadIcon>

<form>
<NameInputContainer>
<FormLabel>Guild Name</FormLabel>
<Input {...register("serverName")} />
</NameInputContainer>
<InputContainer>
<LabelWrapper error={!!errors.name}>
<InputLabel>Guild Name</InputLabel>
{errors.name && (
<InputErrorText>
<>
<Divider>-</Divider>
{errors.name.message}
</>
</InputErrorText>
)}
</LabelWrapper>
<InputWrapper>
<Input
autoFocus
{...register("name", { required: true })}
placeholder="Guild Name"
error={!!errors.name}
disabled={isLoading}
/>
</InputWrapper>
</InputContainer>
</form>
</ModelContentContainer>

<ModalFooter>
<ModalActionItem variant="filled" size="med">
<ModalActionItem
variant="filled"
size="med"
onClick={onSubmit}
disabled={isLoading}
>
Create
</ModalActionItem>

Expand Down
10 changes: 10 additions & 0 deletions src/components/modals/ModalComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@ export const ModalActionItem = styled.button<{
`;
}
}}

// disabled styling
${(props) => {
if (props.disabled) {
return `
opacity: 0.5;
cursor: not-allowed;
`;
}
}}
`;

export const ModalFooter = styled.div`
Expand Down
4 changes: 2 additions & 2 deletions src/pages/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
AuthSwitchPageContainer,
AuthSwitchPageLabel,
AuthSwitchPageLink,
Divider,
FormContainer,
Header,
Input,
Expand All @@ -23,8 +22,8 @@ import {
SubmitButton,
Wrapper,
} from "../components/AuthComponents";
import { Divider } from "../components/Divider";
import HCaptcha, { HeaderContainer } from "../components/HCaptcha";
import MFA from "../components/MFA";
import ForgotPasswordModal from "../components/modals/ForgotPasswordModal";
import { AUTH_NO_BRANDING, useAppStore } from "../stores/AppStore";
import { Globals, RouteSettings } from "../utils/Globals";
Expand All @@ -36,6 +35,7 @@ import {
IAPILoginResponseMFARequired,
} from "../utils/interfaces/api";
import { messageFromFieldError } from "../utils/messageFromFieldError";
import MFA from "./subpages/MFA";

type FormValues = {
login: string;
Expand Down
2 changes: 1 addition & 1 deletion src/pages/RegistrationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
AuthSwitchPageContainer,
AuthSwitchPageLabel,
AuthSwitchPageLink,
Divider,
FormContainer,
Header,
Input,
Expand All @@ -23,6 +22,7 @@ import {
Wrapper,
} from "../components/AuthComponents";
import DOBInput from "../components/DOBInput";
import { Divider } from "../components/Divider";
import HCaptcha from "../components/HCaptcha";
import { AUTH_NO_BRANDING, useAppStore } from "../stores/AppStore";
import {
Expand Down
22 changes: 11 additions & 11 deletions src/components/MFA.tsx → src/pages/subpages/MFA.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,9 @@ import { Routes } from "@spacebarchat/spacebar-api-types/v9";
import React from "react";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { ReactComponent as SpacebarLogoBlue } from "../assets/images/logo/Logo-Blue.svg";
import { useAppStore } from "../stores/AppStore";
import {
IAPIError,
IAPILoginResponseMFARequired,
IAPILoginResponseSuccess,
IAPITOTPRequest,
} from "../utils/interfaces/api";
import { messageFromFieldError } from "../utils/messageFromFieldError";
import { ReactComponent as SpacebarLogoBlue } from "../../assets/images/logo/Logo-Blue.svg";
import {
AuthContainer,
Divider,
FormContainer,
Header,
HeaderContainer,
Expand All @@ -27,7 +18,16 @@ import {
SubHeader,
SubmitButton,
Wrapper,
} from "./AuthComponents";
} from "../../components/AuthComponents";
import { Divider } from "../../components/Divider";
import { useAppStore } from "../../stores/AppStore";
import {
IAPIError,
IAPILoginResponseMFARequired,
IAPILoginResponseSuccess,
IAPITOTPRequest,
} from "../../utils/interfaces/api";
import { messageFromFieldError } from "../../utils/messageFromFieldError";

type FormValues = {
code: string;
Expand Down