@oxyhq/services 0.0.22 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/dot-icon.d.ts +3 -0
- package/dist/assets/dot-icon.d.ts.map +1 -0
- package/dist/assets/dot-icon.js +6 -0
- package/dist/assets/verified-icon.d.ts +3 -0
- package/dist/assets/verified-icon.d.ts.map +1 -0
- package/dist/assets/verified-icon.js +9 -0
- package/dist/components/auth/AccountSwitcherModal.d.ts +5 -0
- package/dist/components/auth/AccountSwitcherModal.d.ts.map +1 -0
- package/dist/components/auth/AccountSwitcherModal.js +29 -0
- package/dist/components/auth/OAvatar.js +1 -1
- package/dist/components/auth/SessionOwnerButton.d.ts +3 -0
- package/dist/components/auth/SessionOwnerButton.d.ts.map +1 -0
- package/dist/components/auth/SessionOwnerButton.js +32 -0
- package/dist/components/elements/button/components/button.d.ts +7 -0
- package/dist/components/elements/button/components/button.d.ts.map +1 -0
- package/dist/components/elements/button/components/button.js +6 -0
- package/dist/components/elements/button/index.d.ts +2 -0
- package/dist/components/elements/button/index.d.ts.map +1 -0
- package/dist/components/elements/button/index.js +1 -0
- package/dist/components/elements/ellipsis-wrapper/components/ellipsis-wrapper.d.ts +5 -0
- package/dist/components/elements/ellipsis-wrapper/components/ellipsis-wrapper.d.ts.map +1 -0
- package/dist/components/elements/ellipsis-wrapper/components/ellipsis-wrapper.js +4 -0
- package/dist/components/elements/ellipsis-wrapper/index.d.ts +2 -0
- package/dist/components/elements/ellipsis-wrapper/index.d.ts.map +1 -0
- package/dist/components/elements/ellipsis-wrapper/index.js +1 -0
- package/dist/components/elements/modal/components/confirmation-modal.d.ts +12 -0
- package/dist/components/elements/modal/components/confirmation-modal.d.ts.map +1 -0
- package/dist/components/elements/modal/components/confirmation-modal.js +21 -0
- package/dist/components/elements/modal/components/modal.d.ts +13 -0
- package/dist/components/elements/modal/components/modal.d.ts.map +1 -0
- package/dist/components/elements/modal/components/modal.js +111 -0
- package/dist/components/elements/modal/hooks/use-track-position.d.ts +5 -0
- package/dist/components/elements/modal/hooks/use-track-position.d.ts.map +1 -0
- package/dist/components/elements/modal/hooks/use-track-position.js +35 -0
- package/dist/components/elements/modal/index.d.ts +4 -0
- package/dist/components/elements/modal/index.d.ts.map +1 -0
- package/dist/components/elements/modal/index.js +3 -0
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/features/profile/components/avatar.d.ts +10 -0
- package/dist/features/profile/components/avatar.d.ts.map +1 -0
- package/dist/features/profile/components/avatar.js +7 -0
- package/dist/features/profile/components/user-name.d.ts +7 -0
- package/dist/features/profile/components/user-name.d.ts.map +1 -0
- package/dist/features/profile/components/user-name.js +8 -0
- package/dist/features/profile/components/user-username.d.ts +5 -0
- package/dist/features/profile/components/user-username.d.ts.map +1 -0
- package/dist/features/profile/components/user-username.js +7 -0
- package/dist/features/profile/index.d.ts +4 -0
- package/dist/features/profile/index.d.ts.map +1 -0
- package/dist/features/profile/index.js +3 -0
- package/dist/hooks/get-user.d.ts +2 -0
- package/dist/hooks/get-user.d.ts.map +1 -0
- package/dist/hooks/get-user.js +27 -0
- package/dist/hooks/use-user.d.ts +14 -0
- package/dist/hooks/use-user.d.ts.map +1 -0
- package/dist/hooks/use-user.js +17 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/utils/cn.d.ts +3 -0
- package/dist/utils/cn.d.ts.map +1 -0
- package/dist/utils/cn.js +5 -0
- package/package.json +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dot-icon.d.ts","sourceRoot":"","sources":["../../src/assets/dot-icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,OAAO,yBAQnB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export const DotIcon = () => {
|
|
3
|
+
return (React.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true" },
|
|
4
|
+
React.createElement("g", null,
|
|
5
|
+
React.createElement("path", { d: "M3 12c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2zm9 2c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm7 0c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z" }))));
|
|
6
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verified-icon.d.ts","sourceRoot":"","sources":["../../src/assets/verified-icon.tsx"],"names":[],"mappings":";AAAA,eAAO,MAAM,YAAY,mCAiBxB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const VerifiedIcon = () => {
|
|
2
|
+
return (React.createElement("svg", { style: {
|
|
3
|
+
fill: "var(--clr-primary)",
|
|
4
|
+
height: "var(--verified-icon-width)",
|
|
5
|
+
marginLeft: "2px",
|
|
6
|
+
}, viewBox: "0 0 24 24", "aria-label": "Verified account", role: "img" },
|
|
7
|
+
React.createElement("g", null,
|
|
8
|
+
React.createElement("path", { d: "M22.25 12c0-1.43-.88-2.67-2.19-3.34.46-1.39.2-2.9-.81-3.91s-2.52-1.27-3.91-.81c-.66-1.31-1.91-2.19-3.34-2.19s-2.67.88-3.33 2.19c-1.4-.46-2.91-.2-3.92.81s-1.26 2.52-.8 3.91c-1.31.67-2.2 1.91-2.2 3.34s.89 2.67 2.2 3.34c-.46 1.39-.21 2.9.8 3.91s2.52 1.26 3.91.81c.67 1.31 1.91 2.19 3.34 2.19s2.68-.88 3.34-2.19c1.39.45 2.9.2 3.91-.81s1.27-2.52.81-3.91c1.31-.67 2.19-1.91 2.19-3.34zm-11.71 4.2L6.8 12.46l1.41-1.42 2.26 2.26 4.8-5.23 1.47 1.36-6.2 6.77z" }))));
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccountSwitcherModal.d.ts","sourceRoot":"","sources":["../../../src/components/auth/AccountSwitcherModal.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,eAAO,MAAM,oBAAoB;aAEpB,MAAM,IAAI;2CAmCrB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { motion } from "framer-motion";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
import useOxySession from "../../hooks/useOxySession";
|
|
6
|
+
import { forwardRef } from "react";
|
|
7
|
+
import { useUser } from "../../hooks/use-user";
|
|
8
|
+
import styles from "./styles/session-owner-modal.module.scss";
|
|
9
|
+
export const AccountSwitcherModal = forwardRef(({ onClose }, ref) => {
|
|
10
|
+
const { session } = useOxySession();
|
|
11
|
+
const { data: user } = useUser({ id: session?.user?.id });
|
|
12
|
+
const style = {
|
|
13
|
+
position: "fixed",
|
|
14
|
+
top: "50%",
|
|
15
|
+
left: "50%",
|
|
16
|
+
transform: "translate(-50%, -50%)",
|
|
17
|
+
};
|
|
18
|
+
if (!session)
|
|
19
|
+
return null;
|
|
20
|
+
return (React.createElement(motion.div, { initial: { opacity: 0, y: "100%" }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: "100%" }, transition: {
|
|
21
|
+
ease: "easeInOut",
|
|
22
|
+
duration: 0.2,
|
|
23
|
+
}, className: styles.container, style: style, role: "group" },
|
|
24
|
+
React.createElement(Link, { href: `/auth/signin`, role: "menuitem", onClick: onClose }, "Add an existing account"),
|
|
25
|
+
React.createElement(Link, { href: `/auth/signout`, role: "menuitem", onClick: onClose },
|
|
26
|
+
"Log out @",
|
|
27
|
+
user?.username)));
|
|
28
|
+
});
|
|
29
|
+
AccountSwitcherModal.displayName = "AccountSwitcherModal";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import styles from "./oavatar.module.css";
|
|
2
|
+
import styles from "./styles/oavatar.module.css";
|
|
3
3
|
import { OxyLogo } from "../assets/oxy-logo";
|
|
4
4
|
import useOxySession from "../../hooks/useOxySession";
|
|
5
5
|
export const OAvatar = ({ icon = React.createElement(OxyLogo, null), text = "Sign in with Oxy", callback = window.location.href, }) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionOwnerButton.d.ts","sourceRoot":"","sources":["../../../src/components/auth/SessionOwnerButton.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAe/B,eAAO,MAAM,kBAAkB,yBAoD9B,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { AnimatePresence } from "framer-motion";
|
|
4
|
+
import useOxySession from "../../hooks/useOxySession";
|
|
5
|
+
import { useRef, useState } from "react";
|
|
6
|
+
import { useUser } from "../../hooks/use-user";
|
|
7
|
+
import { DotIcon } from "../../assets/dot-icon";
|
|
8
|
+
import { Button } from "../../components/elements/button";
|
|
9
|
+
import { EllipsisWrapper } from "../../components/elements/ellipsis-wrapper";
|
|
10
|
+
import { Modal } from "../../components/elements/modal";
|
|
11
|
+
import { Avatar, UserName, UserUsername } from "../../features/profile";
|
|
12
|
+
import { AccountSwitcherModal } from "./AccountSwitcherModal";
|
|
13
|
+
export const SessionOwnerButton = () => {
|
|
14
|
+
const { session } = useOxySession();
|
|
15
|
+
const { data: user } = useUser({ id: session?.user?.id });
|
|
16
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
17
|
+
const buttonRef = useRef(null);
|
|
18
|
+
const openModal = () => {
|
|
19
|
+
setIsModalOpen(true);
|
|
20
|
+
};
|
|
21
|
+
return (React.createElement(React.Fragment, null,
|
|
22
|
+
React.createElement(Button, { "aria-label": "Account menu", onClick: openModal, ref: buttonRef, "aria-haspopup": "menu", "aria-expanded": isModalOpen, className: "p-[0.75em] hover:bg-neutral-500 focus-visible:bg-neutral-500 focus-visible:outline-secondary-100 active:bg-neutral-600 xxl:flex xxl:w-full xxl:gap-3" },
|
|
23
|
+
React.createElement(Avatar, { userImage: session?.user?.avatar }),
|
|
24
|
+
React.createElement("div", { className: "hidden flex-1 flex-col xxl:flex" },
|
|
25
|
+
React.createElement(UserName, { name: session?.user?.name, isVerified: session?.user?.verified }),
|
|
26
|
+
React.createElement(EllipsisWrapper, null,
|
|
27
|
+
React.createElement(UserUsername, { username: user?.username }))),
|
|
28
|
+
React.createElement("div", { className: "hidden fill-secondary-100 xxl:inline [&>svg]:size-h2" },
|
|
29
|
+
React.createElement(DotIcon, null))),
|
|
30
|
+
React.createElement(AnimatePresence, null, isModalOpen && (React.createElement(Modal, { onClose: () => setIsModalOpen(false), background: "none", minViewportWidth: 500 },
|
|
31
|
+
React.createElement(AccountSwitcherModal, { ref: buttonRef, onClose: () => setIsModalOpen(false) }))))));
|
|
32
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface IButton extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
}
|
|
5
|
+
export declare const Button: React.ForwardRefExoticComponent<IButton & React.RefAttributes<HTMLButtonElement>>;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../../../src/components/elements/button/components/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAI1C,UAAU,OAAQ,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACrE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,eAAO,MAAM,MAAM,mFAoBlB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import { cn } from "../../../../utils/cn";
|
|
3
|
+
export const Button = forwardRef(({ children, className, ...props }, ref) => {
|
|
4
|
+
return (React.createElement("button", { ref: ref, ...props, className: cn("grid cursor-pointer place-items-center rounded-full", "transition-colors duration-200 ease-in-out", "fill-secondary-100 p-[0.5em]", "focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary-100", "fill-secondary-100 [&>svg]:w-h2", "disabled-button", className) }, children));
|
|
5
|
+
});
|
|
6
|
+
Button.displayName = "Button";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/elements/button/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Button } from "./components/button";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ellipsis-wrapper.d.ts","sourceRoot":"","sources":["../../../../../src/components/elements/ellipsis-wrapper/components/ellipsis-wrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,eAAO,MAAM,eAAe,kBAEzB;IACD,QAAQ,EAAE,MAAM,SAAS,CAAC;CAC3B,sBAUA,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/elements/ellipsis-wrapper/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./components/ellipsis-wrapper";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export declare const ConfirmationModal: ({ heading, paragraph, confirmButtonText, confirmButtonClick, confirmButtonStyle, cancelButtonText, cancelButtonClick, logo, }: {
|
|
3
|
+
heading: string;
|
|
4
|
+
paragraph: string;
|
|
5
|
+
confirmButtonText: string;
|
|
6
|
+
confirmButtonClick: () => void;
|
|
7
|
+
confirmButtonStyle: "delete" | "unfollow" | "logout";
|
|
8
|
+
cancelButtonText: string;
|
|
9
|
+
cancelButtonClick: () => void;
|
|
10
|
+
logo?: React.ReactNode;
|
|
11
|
+
}) => React.JSX.Element;
|
|
12
|
+
//# sourceMappingURL=confirmation-modal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirmation-modal.d.ts","sourceRoot":"","sources":["../../../../../src/components/elements/modal/components/confirmation-modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAIzC,eAAO,MAAM,iBAAiB,kIAS3B;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,kBAAkB,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IACrD,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,SAAS,CAAC;CACxB,sBAuCA,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
|
+
import { motion } from "framer-motion";
|
|
3
|
+
import styles from "./styles/confirmation-modal.module.scss";
|
|
4
|
+
export const ConfirmationModal = ({ heading, paragraph, confirmButtonText, confirmButtonClick, confirmButtonStyle = "delete", cancelButtonText, cancelButtonClick, logo, }) => {
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
document.body.style.overflow = "hidden";
|
|
7
|
+
document.body.style.paddingRight = "11px";
|
|
8
|
+
return () => {
|
|
9
|
+
document.body.style.overflow = "unset";
|
|
10
|
+
document.body.style.paddingRight = "0";
|
|
11
|
+
};
|
|
12
|
+
}, []);
|
|
13
|
+
return (React.createElement(motion.div, { initial: { opacity: 0, y: 50 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: 50 }, transition: { duration: 0.2 }, className: styles.container },
|
|
14
|
+
logo && React.createElement("div", { className: styles.logo }, logo),
|
|
15
|
+
React.createElement("h1", null, heading),
|
|
16
|
+
React.createElement("p", null, paragraph),
|
|
17
|
+
React.createElement("div", { className: styles.buttons },
|
|
18
|
+
React.createElement("button", { onClick: confirmButtonClick, className: `${styles.confirm} ${styles[confirmButtonStyle]}
|
|
19
|
+
}` }, confirmButtonText),
|
|
20
|
+
React.createElement("button", { onClick: cancelButtonClick, className: styles.cancel }, cancelButtonText))));
|
|
21
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export declare const Modal: ({ children, onClose, closeOnBackdropClick, background, minViewportWidth, maxViewportWidth, disableScroll, focusOnElement, focusAfterClose, }: {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
closeOnBackdropClick?: boolean;
|
|
6
|
+
background?: string;
|
|
7
|
+
minViewportWidth?: number | null;
|
|
8
|
+
maxViewportWidth?: number | null;
|
|
9
|
+
disableScroll?: boolean;
|
|
10
|
+
focusOnElement?: string | null;
|
|
11
|
+
focusAfterClose?: string | null;
|
|
12
|
+
}) => React.ReactPortal;
|
|
13
|
+
//# sourceMappingURL=modal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../../../../src/components/elements/modal/components/modal.tsx"],"names":[],"mappings":"AAKA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAKpE,eAAO,MAAM,KAAK,iJAUf;IACD,QAAQ,EAAE,MAAM,SAAS,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,sBAuJA,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
|
2
|
+
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
|
3
|
+
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
|
|
4
|
+
"use client";
|
|
5
|
+
import { motion } from "framer-motion";
|
|
6
|
+
import React, { useCallback, useLayoutEffect, useRef } from "react";
|
|
7
|
+
import { createPortal } from "react-dom";
|
|
8
|
+
import styles from "./styles/modal.module.scss";
|
|
9
|
+
export const Modal = ({ children, onClose, closeOnBackdropClick = true, background, minViewportWidth = null, maxViewportWidth = null, disableScroll = false, focusOnElement = null, focusAfterClose = null, }) => {
|
|
10
|
+
const modalRef = useRef(null);
|
|
11
|
+
const previouslyFocusedElementRef = useRef(null);
|
|
12
|
+
const handleKeyDown = useCallback((e) => {
|
|
13
|
+
if (e.key === "Escape") {
|
|
14
|
+
onClose();
|
|
15
|
+
}
|
|
16
|
+
if (e.key === "Tab") {
|
|
17
|
+
const modal = modalRef.current;
|
|
18
|
+
if (!modal)
|
|
19
|
+
return;
|
|
20
|
+
const focusableElements = Array.from(modal.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])'));
|
|
21
|
+
const firstFocusableElement = focusableElements[0];
|
|
22
|
+
const lastFocusableElement = focusableElements[focusableElements.length - 1];
|
|
23
|
+
if (e.shiftKey) {
|
|
24
|
+
if (document.activeElement === firstFocusableElement) {
|
|
25
|
+
lastFocusableElement.focus();
|
|
26
|
+
e.preventDefault();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
if (document.activeElement === lastFocusableElement) {
|
|
31
|
+
firstFocusableElement.focus();
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}, [onClose]);
|
|
37
|
+
const handleScroll = useCallback((e) => {
|
|
38
|
+
if (disableScroll) {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
}
|
|
41
|
+
}, [disableScroll]);
|
|
42
|
+
const handleDisplay = useCallback(() => {
|
|
43
|
+
const modal = modalRef.current;
|
|
44
|
+
if (!modal)
|
|
45
|
+
return;
|
|
46
|
+
const viewportWidth = window.innerWidth;
|
|
47
|
+
if ((minViewportWidth && viewportWidth < minViewportWidth) ||
|
|
48
|
+
(maxViewportWidth && viewportWidth > maxViewportWidth)) {
|
|
49
|
+
onClose();
|
|
50
|
+
}
|
|
51
|
+
}, [onClose, minViewportWidth, maxViewportWidth]);
|
|
52
|
+
useLayoutEffect(() => {
|
|
53
|
+
const modal = modalRef.current;
|
|
54
|
+
if (!modal)
|
|
55
|
+
return;
|
|
56
|
+
const focusableElements = Array.from(modal.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])'));
|
|
57
|
+
const firstFocusableElement = focusableElements?.[0];
|
|
58
|
+
previouslyFocusedElementRef.current = document.activeElement;
|
|
59
|
+
modal?.addEventListener("keydown", handleKeyDown);
|
|
60
|
+
if (focusOnElement) {
|
|
61
|
+
const elementToFocus = modal.querySelector(focusOnElement);
|
|
62
|
+
elementToFocus?.focus();
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
firstFocusableElement?.focus();
|
|
66
|
+
}
|
|
67
|
+
if (disableScroll) {
|
|
68
|
+
document.body.style.overflow = "hidden";
|
|
69
|
+
document.body.style.paddingRight = "11px";
|
|
70
|
+
window.addEventListener("scroll", handleScroll);
|
|
71
|
+
}
|
|
72
|
+
if (minViewportWidth || maxViewportWidth) {
|
|
73
|
+
handleDisplay();
|
|
74
|
+
}
|
|
75
|
+
return () => {
|
|
76
|
+
modal?.removeEventListener("keydown", handleKeyDown);
|
|
77
|
+
if (focusAfterClose) {
|
|
78
|
+
const elementToFocus = document.querySelector(focusAfterClose);
|
|
79
|
+
elementToFocus?.focus();
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
previouslyFocusedElementRef.current?.focus();
|
|
83
|
+
}
|
|
84
|
+
if (disableScroll) {
|
|
85
|
+
document.body.style.overflow = "";
|
|
86
|
+
document.body.style.paddingRight = "";
|
|
87
|
+
window.removeEventListener("scroll", handleScroll);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}, [
|
|
91
|
+
onClose,
|
|
92
|
+
disableScroll,
|
|
93
|
+
handleKeyDown,
|
|
94
|
+
handleScroll,
|
|
95
|
+
handleDisplay,
|
|
96
|
+
minViewportWidth,
|
|
97
|
+
maxViewportWidth,
|
|
98
|
+
focusOnElement,
|
|
99
|
+
focusAfterClose,
|
|
100
|
+
]);
|
|
101
|
+
const backdropStyle = {
|
|
102
|
+
backgroundColor: background === "none" ? "transparent" : "var(--clr-modal-background)",
|
|
103
|
+
};
|
|
104
|
+
return createPortal(React.createElement(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, onClick: (e) => {
|
|
105
|
+
e.stopPropagation();
|
|
106
|
+
if (e.currentTarget === e.target && closeOnBackdropClick)
|
|
107
|
+
onClose();
|
|
108
|
+
}, onKeyDown: (e) => {
|
|
109
|
+
e.stopPropagation();
|
|
110
|
+
}, ref: modalRef, className: `${styles.container}`, style: backdropStyle, id: "dialog", role: "dialog", "aria-modal": "true" }, children), document.body);
|
|
111
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-track-position.d.ts","sourceRoot":"","sources":["../../../../../src/components/elements/modal/hooks/use-track-position.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,gCAG1B;IACD,SAAS,EAAE,MAAM,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,mBAuCA,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useLayoutEffect } from "react";
|
|
3
|
+
export const useTrackPosition = ({ buttonRef, trackScroll = false, }) => {
|
|
4
|
+
const [buttonBoundaries, setButtonBoundaries] = useState(buttonRef?.current?.getBoundingClientRect() ?? null);
|
|
5
|
+
useLayoutEffect(() => {
|
|
6
|
+
const handleResize = () => {
|
|
7
|
+
if (buttonRef?.current) {
|
|
8
|
+
setButtonBoundaries(buttonRef.current.getBoundingClientRect());
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
window.addEventListener("resize", handleResize);
|
|
12
|
+
if (trackScroll) {
|
|
13
|
+
window.addEventListener("scroll", handleResize);
|
|
14
|
+
}
|
|
15
|
+
return () => {
|
|
16
|
+
window.removeEventListener("resize", handleResize);
|
|
17
|
+
if (trackScroll) {
|
|
18
|
+
window.removeEventListener("scroll", handleResize);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}, [
|
|
22
|
+
buttonRef,
|
|
23
|
+
buttonRef.current?.getBoundingClientRect,
|
|
24
|
+
trackScroll,
|
|
25
|
+
setButtonBoundaries,
|
|
26
|
+
]);
|
|
27
|
+
useLayoutEffect(() => {
|
|
28
|
+
setButtonBoundaries(buttonRef.current?.getBoundingClientRect() ?? null);
|
|
29
|
+
}, [
|
|
30
|
+
buttonRef,
|
|
31
|
+
buttonRef.current?.getBoundingClientRect,
|
|
32
|
+
setButtonBoundaries,
|
|
33
|
+
]);
|
|
34
|
+
return buttonBoundaries;
|
|
35
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/elements/modal/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC;AAChD,cAAc,4BAA4B,CAAC"}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ declare global {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
export declare const NODE_ENV: "development" | "production"
|
|
18
|
+
export declare const NODE_ENV: "development" | "production";
|
|
19
19
|
export declare const OXY_AUTH_URL: string;
|
|
20
20
|
export {};
|
|
21
21
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,SAAS;;;;;;;;;EAGb,CAAC;AAEH,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,MAAM,CAAC;QACf,UAAU,UAAW,SAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC;SAAG;KAC1D;CACF;AAED,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,SAAS;;;;;;;;;EAGb,CAAC;AAEH,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,MAAM,CAAC;QACf,UAAU,UAAW,SAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC;SAAG;KAC1D;CACF;AAED,eAAO,MAAM,QAAQ,8BAAuB,CAAC;AAC7C,eAAO,MAAM,YAAY,QACoD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface IAvatar extends React.ImgHTMLAttributes<HTMLImageElement> {
|
|
3
|
+
userImage: string | null | undefined;
|
|
4
|
+
className?: string;
|
|
5
|
+
width?: number;
|
|
6
|
+
height?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const Avatar: ({ userImage, className, ...props }: IAvatar) => React.JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=avatar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../../src/features/profile/components/avatar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,OAAQ,SAAQ,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;IACjE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,MAAM,uCAAwC,OAAO,sBAiBjE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import Image from "next/image";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { cn } from "../../../utils/cn";
|
|
4
|
+
export const Avatar = ({ userImage, className, ...props }) => {
|
|
5
|
+
return (React.createElement("div", { className: cn("relative aspect-square w-[calc(var(--tw-fs-kilo)+9px)] overflow-hidden rounded-full", className) },
|
|
6
|
+
React.createElement(Image, { ...props, src: userImage || `/user_placeholder.png`, alt: "profile picture", fill: true, className: "block size-full object-cover" })));
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-name.d.ts","sourceRoot":"","sources":["../../../../src/features/profile/components/user-name.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,eAAO,MAAM,QAAQ,iCAIlB;IACD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B,sBAOA,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { VerifiedIcon } from "../../../assets/verified-icon";
|
|
3
|
+
import styles from "./styles/user-name.module.scss";
|
|
4
|
+
export const UserName = ({ name, isVerified = false, hover = false, }) => {
|
|
5
|
+
return (React.createElement("div", { className: `${styles.container} ${hover ? styles.hover : ""}` },
|
|
6
|
+
name && React.createElement("span", null, name),
|
|
7
|
+
isVerified && React.createElement(VerifiedIcon, null)));
|
|
8
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-username.d.ts","sourceRoot":"","sources":["../../../../src/features/profile/components/user-username.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,eAAO,MAAM,YAAY,kBAEtB;IACD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,sBAEA,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/profile/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-user.d.ts","sourceRoot":"","sources":["../../src/hooks/get-user.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,OAAc,MAAM,GAAG,SAAS,iBAsBnD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
export const getUser = async (id) => {
|
|
3
|
+
try {
|
|
4
|
+
const response = await axios.get(`/api/users/${id}`);
|
|
5
|
+
return response.data;
|
|
6
|
+
}
|
|
7
|
+
catch (error) {
|
|
8
|
+
if (error.response) {
|
|
9
|
+
// The request was made and the server responded with a status code
|
|
10
|
+
// that falls out of the range of 2xx
|
|
11
|
+
console.log(error.response.data);
|
|
12
|
+
console.log(error.response.status);
|
|
13
|
+
console.log(error.response.headers);
|
|
14
|
+
}
|
|
15
|
+
else if (error.request) {
|
|
16
|
+
// The request was made but no response was received
|
|
17
|
+
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
18
|
+
// http.ClientRequest in node.js
|
|
19
|
+
console.log(error.request);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// Something happened in setting up the request that triggered an Error
|
|
23
|
+
console.log("Error", error.message);
|
|
24
|
+
}
|
|
25
|
+
console.log(error.config);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface IUser {
|
|
2
|
+
id: string;
|
|
3
|
+
username: string;
|
|
4
|
+
name: string;
|
|
5
|
+
email: string;
|
|
6
|
+
role: string;
|
|
7
|
+
avatar: string;
|
|
8
|
+
color: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const useUser: ({ id, initialData, }: {
|
|
11
|
+
id: string | undefined;
|
|
12
|
+
initialData?: IUser;
|
|
13
|
+
}) => import("@tanstack/react-query").UseQueryResult<IUser, Error>;
|
|
14
|
+
//# sourceMappingURL=use-user.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-user.d.ts","sourceRoot":"","sources":["../../src/hooks/use-user.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,OAAO,yBAGjB;IACD,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC;CACrB,iEAcA,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
import { getUser } from "./get-user";
|
|
3
|
+
export const useUser = ({ id, initialData, }) => {
|
|
4
|
+
return useQuery({
|
|
5
|
+
queryKey: ["users", id],
|
|
6
|
+
queryFn: async () => {
|
|
7
|
+
if (!id) {
|
|
8
|
+
// Return a default value or null when id is not provided
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return getUser(id);
|
|
12
|
+
},
|
|
13
|
+
refetchOnWindowFocus: false,
|
|
14
|
+
initialData: initialData ?? undefined,
|
|
15
|
+
enabled: !!id, // Only run the query if the id is provided
|
|
16
|
+
});
|
|
17
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import useOxySession from "./hooks/useOxySession";
|
|
2
2
|
import getUserById from "./hooks/getUserById";
|
|
3
3
|
import SignInButton from "./components/auth/SignInButton";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
export { useOxySession, getUserById, SignInButton,
|
|
4
|
+
import { AccountSwitcherModal } from "./components/auth/AccountSwitcherModal";
|
|
5
|
+
import { SessionOwnerButton } from "./components/auth/SessionOwnerButton";
|
|
6
|
+
export { useOxySession, getUserById, SignInButton, AccountSwitcherModal, SessionOwnerButton, };
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,uBAAuB,CAAC;AAClD,OAAO,WAAW,MAAM,qBAAqB,CAAC;AAC9C,OAAO,YAAY,MAAM,gCAAgC,CAAC;AAC1D,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,uBAAuB,CAAC;AAClD,OAAO,WAAW,MAAM,qBAAqB,CAAC;AAC9C,OAAO,YAAY,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAE1E,OAAO,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,GACnB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import useOxySession from "./hooks/useOxySession";
|
|
2
2
|
import getUserById from "./hooks/getUserById";
|
|
3
3
|
import SignInButton from "./components/auth/SignInButton";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
export { useOxySession, getUserById, SignInButton,
|
|
4
|
+
import { AccountSwitcherModal } from "./components/auth/AccountSwitcherModal";
|
|
5
|
+
import { SessionOwnerButton } from "./components/auth/SessionOwnerButton";
|
|
6
|
+
export { useOxySession, getUserById, SignInButton, AccountSwitcherModal, SessionOwnerButton, };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../../src/utils/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAG7C,eAAO,MAAM,EAAE,cAAe,UAAU,EAAE,WAEzC,CAAC"}
|
package/dist/utils/cn.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/services",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.24",
|
|
4
4
|
"description": "",
|
|
5
5
|
"homepage": "https://oxy.so/",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -39,11 +39,15 @@
|
|
|
39
39
|
"typescript": "^5.4.5"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
+
"@tanstack/react-query": "^5.40.0",
|
|
42
43
|
"axios": "^1.6.8",
|
|
44
|
+
"clsx": "^2.1.1",
|
|
43
45
|
"dotenv": "^16.4.5",
|
|
46
|
+
"framer-motion": "^11.2.9",
|
|
44
47
|
"localforage": "^1.10.0",
|
|
45
48
|
"react": "^18.3.1",
|
|
46
49
|
"react-dom": "^18.3.1",
|
|
50
|
+
"tailwind-merge": "^2.3.0",
|
|
47
51
|
"zod": "^3.23.8",
|
|
48
52
|
"zustand": "^4.5.2"
|
|
49
53
|
}
|