Skip to content

Commit

Permalink
Merge pull request #41 from Prodeko:device-detection
Browse files Browse the repository at this point in the history
Device-detection
  • Loading branch information
ccruzkauppila authored Oct 29, 2024
2 parents 7f532a8 + 8ee4d55 commit 45c97b5
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 24 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"js-sha256": "^0.11.0",
"lodash": "^4.17.21",
"next": "15.0.1-canary.2",
"next-qrcode": "^2.5.1",
"qrcode.react": "^3.1.0",
"react": "19.0.0-rc-69d4b800-20241021",
"react-chartjs-2": "^5.2.0",
Expand Down
154 changes: 152 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/app/(loggedin)/account/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { InfoCard, InfoCardLoading } from "@/components/ui/InfoCard";
import { RfidSetupDialog } from "@/components/ui/RfidSetupDialog";
import { SectionTitle } from "@/components/ui/SectionTitle";
import { getCurrentUserBalance } from "@/server/actions/account/getBalance";
import { logoutAction } from "@/server/actions/auth/logout";
import { getCurrentUser } from "@/server/db/queries/account";

const AccountPage = () => {
Expand Down Expand Up @@ -84,11 +85,11 @@ const AccountPage = () => {

<div className="px-6 md:px-12">
<FatButton
href="/"
text="logout"
RightIcon={HiLogout}
buttonType="a"
buttonType="button"
intent="secondary"
onClick={() => logoutAction()}
fullwidth
/>
</div>
Expand Down
9 changes: 8 additions & 1 deletion src/app/(loggedout)/login/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import toast from "react-hot-toast";
import { HiLogin } from "react-icons/hi";

import { LoginFormState } from "@/common/types";
import { RFID_ALLOWED_DEVICE_TYPE, getDeviceType } from "@/common/utils";
import { FatButton } from "@/components/ui/Buttons/FatButton";
import { InputWithLabel } from "@/components/ui/Input";
import { RfidLoginDialog } from "@/components/ui/RfidLoginDialog";
Expand All @@ -21,6 +22,12 @@ export const LoginForm = () => {
message: "",
});

const deviceType = useRef<string>(null);
useEffect(() => {
// Getdevicetype references navigator which is not defined before page load
deviceType.current = getDeviceType();
}, []);

useEffect(() => {
if (state.message) {
if (toastIdRef.current) {
Expand Down Expand Up @@ -68,7 +75,7 @@ export const LoginForm = () => {
/>
</div>
<div className="flex w-full gap-4">
<RfidLoginDialog />
{deviceType.current === RFID_ALLOWED_DEVICE_TYPE && <RfidLoginDialog />}
<SubmitButton />
</div>
</form>
Expand Down
29 changes: 28 additions & 1 deletion src/common/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import { clientEnv } from "@/env/client.mjs";
import { ValueError } from "@/server/exceptions/exception";

Expand Down Expand Up @@ -111,3 +110,31 @@ export const parseISOString = (s: string) => {
),
);
};

/**
* Get the type of device the user is browsing on. Used to determine e.g. available login & payment methods.
* Only works in client components!
* - RFID login & setup should only be available on the guild room tablet.
* - MobilePay links should only be shown to users on their personal mobile devices.
* - Stripe payment should not be available on the guild room tablet.
* - MobilePay QR & manual payment instructions should be shown on desktop and on the guild room tablet
* @returns "Mobile" | "Desktop" | "GuildroomTablet"
*/
export const getDeviceType = (): "Mobile" | "Desktop" | "GuildroomTablet" => {
if (navigator && "userAgent" in navigator) {
const ua = navigator.userAgent;
// TODO: Check actual model name from user agent string
const isGuildroomTablet =
ua.includes("Armor") && ua.includes("Pad") && ua.includes("Pro");

if (isGuildroomTablet) return "GuildroomTablet";
if (ua.includes("Mobi")) return "Mobile";
return "Desktop";
}
throw new Error("User agent not available");
};

/**
* Should be "GuildroomTablet" in production.
*/
export const RFID_ALLOWED_DEVICE_TYPE = "Mobile";
Loading

0 comments on commit 45c97b5

Please sign in to comment.