generated from nhcarrigan/template
feat: add mobile games (#42)
### Explanation _No response_ ### Issue _No response_ ### Attestations - [x] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/) - [x] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/). - [x] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/). ### Dependencies - [ ] I have pinned the dependencies to a specific patch version. ### Style - [x] I have run the linter and resolved any errors. - [x] My pull request uses an appropriate title, matching the conventional commit standards. - [x] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request. ### Tests - [x] My contribution adds new code, and I have added tests to cover it. - [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes. - [x] All new and existing tests pass locally with my changes. - [x] Code coverage remains at or above the configured threshold. ### Documentation _No response_ ### Versioning Minor - My pull request introduces a new non-breaking feature. Reviewed-on: https://codeberg.org/nhcarrigan/portfolio/pulls/42 Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com> Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
"use client";
|
||||
import { faAndroid, faAppStore } from "@fortawesome/free-brands-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useState, type JSX } from "react";
|
||||
|
||||
interface PlayProperties {
|
||||
name: string;
|
||||
userId: string;
|
||||
android: string;
|
||||
ios: string;
|
||||
server?: string;
|
||||
guild?: {
|
||||
name: string;
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
const copyToClipboard = (text: string): void => {
|
||||
void navigator.clipboard.writeText(text);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the view for a mobile game.
|
||||
* @param properties - The game to render.
|
||||
* @returns A JSX element.
|
||||
*/
|
||||
export const PlayComponent = (properties: PlayProperties): JSX.Element => {
|
||||
const { name, android, ios, server, guild, userId } = properties;
|
||||
|
||||
const [ isFriendCodeCopied, setIsFriendCodeCopied ]
|
||||
= useState<boolean>(false);
|
||||
const [ isGuildIdCopied, setIsGuildIdCopied ]
|
||||
= useState<boolean>(false);
|
||||
|
||||
const columns = guild
|
||||
? "grid-cols-[2fr,1fr,200px]"
|
||||
: "grid-cols-[2fr,200px]";
|
||||
|
||||
return (
|
||||
<div className={`grid items-center gap-2.5 pb-10 w-full ${columns}`}>
|
||||
<button
|
||||
className="border-solid border-2 rounded-full p-2
|
||||
text-[--background] bg-[--foreground]
|
||||
hover:bg-[--background] hover:text-[--foreground]"
|
||||
onClick={() => {
|
||||
copyToClipboard(userId);
|
||||
setIsFriendCodeCopied(true);
|
||||
setTimeout(() => {
|
||||
setIsFriendCodeCopied(false);
|
||||
}, 2000);
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
<h2 className="text-2xl">{name}</h2>
|
||||
<p>{`Friend Code: ${isFriendCodeCopied
|
||||
? "Copied!"
|
||||
: userId}`}</p>
|
||||
{typeof server === "string"
|
||||
? <p className="text-sm">{`Server: ${server}`}</p>
|
||||
: null}
|
||||
</button>
|
||||
{guild
|
||||
? <button
|
||||
className="border-solid border-2 rounded-full p-2
|
||||
text-[--background] bg-[--foreground]
|
||||
hover:bg-[--background] hover:text-[--foreground]"
|
||||
onClick={() => {
|
||||
copyToClipboard(userId);
|
||||
setIsGuildIdCopied(true);
|
||||
setTimeout(() => {
|
||||
setIsGuildIdCopied(false);
|
||||
}, 2000);
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
<p className="text-2xl">{"Guild"}</p>
|
||||
<p>{guild.name}</p>
|
||||
<p className="text-sm">{`ID: ${isGuildIdCopied
|
||||
? "Copied!"
|
||||
: guild.id}`}</p>
|
||||
</button>
|
||||
: null}
|
||||
<div className="flex">
|
||||
<a
|
||||
aria-label={`Play ${name} on Android`}
|
||||
className="flex m-auto justify-between
|
||||
items-center border-solid border-2 rounded-full p-2
|
||||
bg-[#3DDC84] text-[#FFFFFF] hover:bg-[#FFFFFF] hover:text-[#3DDC84]"
|
||||
href={android}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<FontAwesomeIcon icon={faAndroid} size="3x" />
|
||||
</a>
|
||||
<a
|
||||
aria-label={`Play ${name} on iOS`}
|
||||
className="flex m-auto justify-between
|
||||
items-center border-solid border-2 rounded-full p-2
|
||||
bg-[#1ba7f8] text-[#FFFFFF] hover:bg-[#FFFFFF] hover:text-[#1ba7f8]"
|
||||
href={ios}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<FontAwesomeIcon icon={faAppStore} size="3x" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user