diff --git a/src/routes/401.tsx b/src/routes/401.tsx index bc71b73..da832d7 100644 --- a/src/routes/401.tsx +++ b/src/routes/401.tsx @@ -1,4 +1,4 @@ -import { Title } from "@solidjs/meta"; +import { Title, Meta } from "@solidjs/meta"; import { HttpStatusCode } from "@solidjs/start"; import { useNavigate } from "@solidjs/router"; import { createEffect, createSignal, For } from "solid-js"; @@ -47,7 +47,11 @@ export default function Page_401() { return ( <> - 401 - Unauthorized + 401 Unauthorized | Michael Freno +
{/* Animated particle background */} diff --git a/src/routes/[...404].tsx b/src/routes/[...404].tsx index 9b55e62..918dcdc 100644 --- a/src/routes/[...404].tsx +++ b/src/routes/[...404].tsx @@ -1,4 +1,4 @@ -import { Title } from "@solidjs/meta"; +import { Title, Meta } from "@solidjs/meta"; import { HttpStatusCode } from "@solidjs/start"; import { useNavigate } from "@solidjs/router"; import { createEffect, createSignal, For } from "solid-js"; @@ -43,7 +43,11 @@ export default function NotFound() { return ( <> - 404 - Not Found + 404 Not Found | Michael Freno +
{/* Animated particle background */} diff --git a/src/routes/about.tsx b/src/routes/about.tsx index c1c2dcf..3aaf89f 100644 --- a/src/routes/about.tsx +++ b/src/routes/about.tsx @@ -1,10 +1,17 @@ -import { Title } from "@solidjs/meta"; +import { Title, Meta } from "@solidjs/meta"; export default function About() { return ( -
- About -

About

-
+ <> + About | Michael Freno + + +
+

About

+
+ ); } diff --git a/src/routes/account.tsx b/src/routes/account.tsx index 3c91809..d5ab908 100644 --- a/src/routes/account.tsx +++ b/src/routes/account.tsx @@ -1,4 +1,5 @@ import { createSignal, createEffect, Show, onMount } from "solid-js"; +import { Title, Meta } from "@solidjs/meta"; import { useNavigate, cache, redirect } from "@solidjs/router"; import { getEvent } from "vinxi/http"; import Eye from "~/components/icons/Eye"; @@ -453,389 +454,407 @@ export default function AccountPage() { }; return ( -
-
- -
Loading...
-
- } - > - {(currentUser) => ( - <> -
- Account Settings -
+ <> + Account | Michael Freno + - {/* Profile Image Section */} -
-
-
- Profile Image -
-
- - -
-
- -
- -
- Profile image updated! +
-
-
-
- -
- - {/* Email Section */} -
-
-
-
- Current email: -
- {currentUser().email ? ( - {currentUser().email} - ) : ( - - None Set - - )} -
- - - -
- -
-
- - - -
-
- -
- -
- Email updated! -
-
-
- - {/* Display Name Section */} -
-
-
- Display Name: -
- {currentUser().displayName ? ( - {currentUser().displayName} - ) : ( - - None Set - - )} +
+ +
+ +
+ Profile image updated! +
+
-
-
- - - -
-
- -
- -
- Display name updated! +
+ + {/* Email Section */} +
+
+
+
+ Current email: +
+ {currentUser().email ? ( + {currentUser().email} + ) : ( + + None Set + + )}
- - -
- - {/* Password Change/Set Section */} -
-
-
- {currentUser().hasPassword - ? "Change Password" - : "Set Password"} + + +
- -
+ +
+ + +
+
+ +
+ +
+ Email updated! +
+
+ + + {/* Display Name Section */} +
+
+
+ Display Name: +
+ {currentUser().displayName ? ( + {currentUser().displayName} + ) : ( + + None Set + + )} +
+
+ +
+
+ + + +
+
+ +
+ +
+ Display name updated! +
+
+
+
+ + {/* Password Change/Set Section */} +
+
+
+ {currentUser().hasPassword + ? "Change Password" + : "Set Password"} +
+ + +
+ + + + +
+
+ +
+ - +
- -
- - - - -
- - -
- Password too short! Min Length: 8 -
-
- -
- - - - -
- - = 6 - } - > -
- Passwords do not match! -
-
- - - - -
- {currentUser().hasPassword - ? "Password did not match record" - : "Error setting password"} -
-
- - -
- Password {currentUser().hasPassword ? "changed" : "set"}{" "} - successfully! -
-
-
-
- -
- - {/* Delete Account Section */} -
-
-
- Delete Account -
-
- Warning: This will delete all account information and is - irreversible -
- -
-
-
- - - + +
+ Password too short! Min Length: 8
+
+ +
+ + + +
+ = 6 + } + > +
+ Passwords do not match! +
+
+ - -
- Password did not match record + +
+ {currentUser().hasPassword + ? "Password did not match record" + : "Error setting password"}
- + + +
+ Password {currentUser().hasPassword ? "changed" : "set"}{" "} + successfully! +
+
+
+ + +
+ + {/* Delete Account Section */} +
+
+
+ Delete Account +
+
+ Warning: This will delete all account information and is + irreversible +
+ +
+
+
+ + + +
+
+ + + + +
+ Password did not match record +
+
+
+
-
- - )} - + + )} + +
-
+ ); } diff --git a/src/routes/blog/[title]/index.tsx b/src/routes/blog/[title]/index.tsx index 23cb265..f5a4bfa 100644 --- a/src/routes/blog/[title]/index.tsx +++ b/src/routes/blog/[title]/index.tsx @@ -1,6 +1,6 @@ import { Show, Suspense, For } from "solid-js"; import { useParams, A, Navigate, query } from "@solidjs/router"; -import { Title } from "@solidjs/meta"; +import { Title, Meta } from "@solidjs/meta"; import { createAsync } from "@solidjs/router"; import { getRequestEvent } from "solid-js/web"; import SessionDependantLike from "~/components/blog/SessionDependantLike"; @@ -159,6 +159,13 @@ export default function PostPage() { {p().title.replaceAll("_", " ")} | Michael Freno +
{/* Fixed banner image background */} diff --git a/src/routes/blog/create/index.tsx b/src/routes/blog/create/index.tsx index 59a3815..9d66ea4 100644 --- a/src/routes/blog/create/index.tsx +++ b/src/routes/blog/create/index.tsx @@ -1,6 +1,6 @@ import { Show, createSignal, createEffect, onCleanup } from "solid-js"; import { useNavigate, query } from "@solidjs/router"; -import { Title } from "@solidjs/meta"; +import { Title, Meta } from "@solidjs/meta"; import { createAsync } from "@solidjs/router"; import { getRequestEvent } from "solid-js/web"; import { api } from "~/lib/api"; @@ -195,6 +195,10 @@ export default function CreatePost() { return ( <> Create Blog Post | Michael Freno + Edit Post | Michael Freno + -
-
-
- What will happen: + <> + Account Deletion - Life and Lineage | Michael Freno + +
+
+
+
+ What will happen: +
+ Once you send, if a match to the email provided is found in our + system, a 24hr grace period is started where you can request a + cancellation of the account deletion. Once the grace period ends, + the account's entry in our central database will be completely + removed, and your individual database storing your remote saves will + also be deleted. No data related to the account is retained in any + way.
- Once you send, if a match to the email provided is found in our - system, a 24hr grace period is started where you can request a - cancellation of the account deletion. Once the grace period ends, the - account's entry in our central database will be completely removed, - and your individual database storing your remote saves will also be - deleted. No data related to the account is retained in any way. -
- + +
-
+ ); } diff --git a/src/routes/downloads.tsx b/src/routes/downloads.tsx index 54aa28d..f41bea6 100644 --- a/src/routes/downloads.tsx +++ b/src/routes/downloads.tsx @@ -1,3 +1,4 @@ +import { Title, Meta } from "@solidjs/meta"; import { A } from "@solidjs/router"; import DownloadOnAppStore from "~/components/icons/DownloadOnAppStore"; import GitHub from "~/components/icons/GitHub"; @@ -21,147 +22,155 @@ export default function DownloadsPage() { }; return ( -
-
- Downloads -
+ <> + Downloads | Michael Freno + -
-
- Life and Lineage -
-
- -
-
-
Android (apk only)
- -
- Note the android version is not well tested, and has performance - issues. -
-
Or
- -
(Coming soon)
- -
- -
-
iOS
- - - -
-
-
- -
-
- Shapes with Abigail! -
- (apk and iOS) -
- -
-
-
Android
- -
Or
-
(Coming soon)
- -
- -
-
iOS
- - - -
+
+
+ Downloads
- Cork + Life and Lineage
- (macOS 13 Ventura or later)
-
- -
-
- Just unzip and drag into 'Applications' folder +
+
+
Android (apk only)
+ +
+ Note the android version is not well tested, and has performance + issues. +
+
Or
+ +
(Coming soon)
+ +
+ +
+
iOS
+ + + +
- +
+
+ Shapes with Abigail! +
+ (apk and iOS) +
+ +
+
+
Android
+ +
Or
+
(Coming soon)
+ +
+ +
+
iOS
+ + + +
+
+ +
+
+ Cork +
+ (macOS 13 Ventura or later) +
+ +
+ +
+
+ Just unzip and drag into 'Applications' folder +
+
+ + +
-
+ ); } diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 8dd73b7..e32638e 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -1,155 +1,164 @@ +import { Title, Meta } from "@solidjs/meta"; import DownloadOnAppStore from "~/components/icons/DownloadOnAppStore"; import { Typewriter } from "~/components/Typewriter"; export default function Home() { return ( -
-
- -
Hey!
-
- -
- My name is Mike Freno, I'm a{" "} - Software Engineer based in{" "} - Brooklyn, NY. -
-
- - I'm a passionate dev tooling, game, and open source software - developer. Recently been working in the world of{" "} - - LÖVE - {" "} - (an open source game engine for Lua). - - - You can see some of my work{" "} - - here (github). - - -
-
Some of my recent projects:
-
- {/* Life and Lineage */} -
-
My mobile game:
- - Life and Lineage - -
-
- Life and Lineage Home -
-
-
-
- Life and Lineage Shops + <> + Home | Michael Freno + + +
+
+ +
Hey!
+
+ +
+ My name is Mike Freno, I'm a{" "} + Software Engineer based in{" "} + Brooklyn, NY. +
+
+ + I'm a passionate dev tooling, game, and open source software + developer. Recently been working in the world of{" "} + + LÖVE + {" "} + (an open source game engine for Lua). + + + You can see some of my work{" "} + + here (github). + + +
+
Some of my recent projects:
+
+ {/* Life and Lineage */} +
+
My mobile game:
+ + Life and Lineage + +
+
+ Life and Lineage Home +
+
+
+
+ Life and Lineage Shops +
-
- {/* FlexLöve */} -
-
My LÖVE UI library
- - FlexLöve - -
-
-
-
-
-
-
-
-
- And if you love the color schemes of this site (which of course you - do), you can see{" "} - - here - {" "} - - and also see the rest of my various dot files idk. There's a macos - and arch linux rice in there if you're into that kinda thing and a - home server setup too. Which I will write about soon™. -
-
- -
- -
- My Collection of -
- By-the-ways: +
+ And if you love the color schemes of this site (which of course you + do), you can see{" "} + + here + {" "} + - and also see the rest of my various dot files idk. There's a macos + and arch linux rice in there if you're into that kinda thing and a + home server setup too. Which I will write about soon™.
- - -
    -
  • I use Neovim
  • -
  • I use Arch Linux
  • -
  • I use Rust
  • -
-
-
-
+
+ +
+ +
+ My Collection of +
+ By-the-ways: +
+
+ +
    +
  • I use Neovim
  • +
  • I use Arch Linux
  • +
  • I use Rust
  • +
+
+
+
+ ); } diff --git a/src/routes/login/index.tsx b/src/routes/login/index.tsx index 667e027..90d391c 100644 --- a/src/routes/login/index.tsx +++ b/src/routes/login/index.tsx @@ -6,6 +6,7 @@ import { cache, redirect } from "@solidjs/router"; +import { Title, Meta } from "@solidjs/meta"; import { getEvent } from "vinxi/http"; import GoogleLogo from "~/components/icons/GoogleLogo"; import GitHub from "~/components/icons/GitHub"; @@ -320,324 +321,331 @@ export default function LoginPage() { }; return ( -
- {/* Logo section - hidden on mobile */} - {/* */} + <> + Login | Michael Freno + +
+ {/* Logo section - hidden on mobile */} + {/* */} - {/* Main content */} -
- {/* Error message */} -
- - Passwords did not match! - - Email Already Exists! -
+ {/* Main content */} +
+ {/* Error message */} +
+ + Passwords did not match! + + Email Already Exists! +
- {/* Title */} -
- {register() ? "Register" : "Login"} -
+ {/* Title */} +
+ {register() ? "Register" : "Login"} +
- {/* Toggle Register/Login */} - + Already have an account? + +
+ } + >
- Already have an account? + Don't have an account yet?
- } - > -
- Don't have an account yet? - -
- - - {/* Form */} -
- {/* Email input */} -
-
- - - -
-
- - {/* Password input - shown for login with password or registration */} - -
-
- - - -
- -
-
- Password too short! Min Length: 8 -
- {/* Password confirmation - shown only for registration */} - -
+ {/* Form */} + + {/* Email input */} +
- +
- +
+
+ Password too short! Min Length: 8 +
+ + + {/* Password confirmation - shown only for registration */} + +
+
+ - - + + +
+ +
+
= 6 + ? "" + : "opacity-0 select-none" + } text-center text-red-500 transition-opacity duration-200 ease-in-out`} + > + Passwords do not match! +
+
+ + {/* Remember Me checkbox */} +
+ +
Remember Me
+ + {/* Error/Success messages */}
= 6 - ? "" - : "opacity-0 select-none" - } text-center text-red-500 transition-opacity duration-200 ease-in-out`} + showPasswordError() + ? "text-red-500" + : showPasswordSuccess() + ? "text-green-500" + : "opacity-0 select-none" + } flex min-h-[16px] justify-center italic transition-opacity duration-300 ease-in-out`} > - Passwords do not match! + + Credentials did not match any record + + + Login Success! Redirecting... + +
+ + {/* Submit button or countdown timer */} +
+ 0} + fallback={ + + } + > + + {renderTime} + + + + {/* Toggle password/email link */} + + + + + + +
+ + + {/* Password reset link */} + +
+ Trouble Logging In?{" "} + + Reset Password +
- {/* Remember Me checkbox */} -
- -
Remember Me
-
- - {/* Error/Success messages */} + {/* Email sent confirmation */}
- - Credentials did not match any record - - - Login Success! Redirecting... - + Email Sent!
- {/* Submit button or countdown timer */} -
- 0} - fallback={ - - } - > - Or
+ + {/* OAuth buttons */} +
+
+ {/* Google OAuth */} + - {renderTime} - - + {register() ? "Register " : "Sign in "} with Google + + + + - {/* Toggle password/email link */} - - - - - - -
- - - {/* Password reset link */} - - - - - {/* Email sent confirmation */} -
- Email Sent! -
- - {/* Or divider */} -
Or
- - {/* OAuth buttons */} -
-
- {/* Google OAuth */} - - {register() ? "Register " : "Sign in "} with Google - - - - - - {/* GitHub OAuth */} - - {register() ? "Register " : "Sign in "} with Github - - - - + {register() ? "Register " : "Sign in "} with Github + + + + +
-
+ ); } diff --git a/src/routes/login/password-reset.tsx b/src/routes/login/password-reset.tsx index 91b373a..8c5f619 100644 --- a/src/routes/login/password-reset.tsx +++ b/src/routes/login/password-reset.tsx @@ -1,5 +1,6 @@ import { createSignal, createEffect, Show } from "solid-js"; import { A, useNavigate, useSearchParams } from "@solidjs/router"; +import { Title, Meta } from "@solidjs/meta"; import CountdownCircleTimer from "~/components/CountdownCircleTimer"; import Eye from "~/components/icons/Eye"; import EyeSlash from "~/components/icons/EyeSlash"; @@ -13,8 +14,10 @@ export default function PasswordResetPage() { const [passwordBlurred, setPasswordBlurred] = createSignal(false); const [passwordChangeLoading, setPasswordChangeLoading] = createSignal(false); const [passwordsMatch, setPasswordsMatch] = createSignal(false); - const [showPasswordLengthWarning, setShowPasswordLengthWarning] = createSignal(false); - const [passwordLengthSufficient, setPasswordLengthSufficient] = createSignal(false); + const [showPasswordLengthWarning, setShowPasswordLengthWarning] = + createSignal(false); + const [passwordLengthSufficient, setPasswordLengthSufficient] = + createSignal(false); const [showRequestNewEmail, setShowRequestNewEmail] = createSignal(false); const [countDown, setCountDown] = createSignal(false); const [error, setError] = createSignal(""); @@ -70,8 +73,8 @@ export default function PasswordResetPage() { body: JSON.stringify({ token: token, newPassword, - newPasswordConfirmation: newPasswordConf, - }), + newPasswordConfirmation: newPasswordConf + }) }); const result = await response.json(); @@ -158,164 +161,179 @@ export default function PasswordResetPage() { } return (
-
Change Successful!
-
{timeRemaining}
-
Redirecting...
+
+ Change Successful! +
+
+ {timeRemaining} +
+
+ Redirecting... +
); }; return ( -
-
- Set New Password -
- -
setNewPasswordTrigger(e)} - class="mt-4 flex w-full justify-center" - > -
- {/* New Password Input */} -
- - - - -
- - {/* Password Length Warning */} -
- Password too short! Min Length: 8 -
- - {/* Password Confirmation Input */} -
- - - - -
- - {/* Password Mismatch Warning */} -
= 6 - ? "" - : "select-none opacity-0" - } transition-opacity text-center text-red-500 text-sm duration-200 ease-in-out mt-2`} - > - Passwords do not match! -
- - {/* Countdown Timer or Submit Button */} - - {passwordChangeLoading() ? "Setting..." : "Set New Password"} - - } - > -
- false} - > - {({ remainingTime }) => renderTime(remainingTime)} - -
-
+ <> + Reset Password | Michael Freno + +
+
+ Set New Password
- - {/* Error Message */} - -
-
{error()}
-
-
- - {/* Token Expired Message */} - +
+ {/* New Password Input */} +
+ + + + +
- {/* Back to Login Link */} - -
+ {/* Password Length Warning */} +
+ Password too short! Min Length: 8 +
+ + {/* Password Confirmation Input */} +
+ + + + +
+ + {/* Password Mismatch Warning */} +
= 6 + ? "" + : "opacity-0 select-none" + } mt-2 text-center text-sm text-red-500 transition-opacity duration-200 ease-in-out`} + > + Passwords do not match! +
+ + {/* Countdown Timer or Submit Button */} + + {passwordChangeLoading() ? "Setting..." : "Set New Password"} + + } + > +
+ false} + > + {({ remainingTime }) => renderTime(remainingTime)} + +
+
+
+ + + {/* Error Message */} + +
+
{error()}
+
+
+ + {/* Token Expired Message */} +
+ Token has expired, request a new one{" "} - Back to Login + here
-
-
+ + {/* Back to Login Link */} + + + +
+ ); } diff --git a/src/routes/login/request-password-reset.tsx b/src/routes/login/request-password-reset.tsx index b83daec..7f83ef2 100644 --- a/src/routes/login/request-password-reset.tsx +++ b/src/routes/login/request-password-reset.tsx @@ -1,5 +1,6 @@ import { createSignal, createEffect, onCleanup, Show } from "solid-js"; import { A, useNavigate } from "@solidjs/router"; +import { Title, Meta } from "@solidjs/meta"; import CountdownCircleTimer from "~/components/CountdownCircleTimer"; import { isValidEmail } from "~/lib/validation"; import { getClientCookie } from "~/lib/cookies.client"; @@ -37,7 +38,10 @@ export default function RequestPasswordResetPage() { createEffect(() => { const timer = getClientCookie("passwordResetRequested"); if (timer) { - timerInterval = setInterval(() => calcRemainder(timer), 1000) as unknown as number; + timerInterval = setInterval( + () => calcRemainder(timer), + 1000 + ) as unknown as number; onCleanup(() => { if (timerInterval) { clearInterval(timerInterval); @@ -71,7 +75,7 @@ export default function RequestPasswordResetPage() { const response = await fetch("/api/trpc/auth.requestPasswordReset", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ email }), + body: JSON.stringify({ email }) }); const result = await response.json(); @@ -115,90 +119,97 @@ export default function RequestPasswordResetPage() { }; return ( -
-
- Password Reset Request -
- -
requestPasswordResetTrigger(e)} - class="mt-4 flex w-full justify-center" - > -
- {/* Email Input */} -
- - - -
- - {/* Countdown Timer or Submit Button */} - 0} - fallback={ - - } - > -
- false} - > - {renderTime} - -
-
+ <> + Request Password Reset | Michael Freno + +
+
+ Password Reset Request
- - {/* Success Message */} -
- If email exists, you will receive an email shortly! -
- - {/* Error Message */} - -
-
{error()}
-
-
- - {/* Back to Login Link */} -
- requestPasswordResetTrigger(e)} + class="mt-4 flex w-full justify-center" > - Back to Login - +
+ {/* Email Input */} +
+ + + +
+ + {/* Countdown Timer or Submit Button */} + 0} + fallback={ + + } + > +
+ false} + > + {renderTime} + +
+
+
+ + + {/* Success Message */} +
+ If email exists, you will receive an email shortly! +
+ + {/* Error Message */} + +
+
{error()}
+
+
+ + {/* Back to Login Link */} +
-
+ ); } diff --git a/src/routes/marketing/life-and-lineage.tsx b/src/routes/marketing/life-and-lineage.tsx index f818319..9c6bb99 100644 --- a/src/routes/marketing/life-and-lineage.tsx +++ b/src/routes/marketing/life-and-lineage.tsx @@ -1,46 +1,52 @@ import { A } from "@solidjs/router"; +import { Title, Meta } from "@solidjs/meta"; import SimpleParallax from "~/components/SimpleParallax"; import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark"; export default function LifeAndLineageMarketing() { return ( - -
-
- Lineage App Icon -
-

- Life and Lineage -

-

A dark fantasy adventure

-
- - - - + <> + Life and Lineage | Michael Freno + + +
+
google-play - +
+

Life and Lineage

+

A dark fantasy adventure

+
-
- + + ); } diff --git a/src/routes/privacy-policy/life-and-lineage.tsx b/src/routes/privacy-policy/life-and-lineage.tsx index 50471de..ce1eee9 100644 --- a/src/routes/privacy-policy/life-and-lineage.tsx +++ b/src/routes/privacy-policy/life-and-lineage.tsx @@ -1,99 +1,107 @@ import { A } from "@solidjs/router"; +import { Title, Meta } from "@solidjs/meta"; export default function PrivacyPolicy() { return ( -
-
Life and Lineage's Privacy Policy
-
Last Updated: October 22, 2024
-
- Welcome to Life and Lineage ('We', 'Us', - 'Our'). Your privacy is important to us. This privacy policy - will help you understand our policies and procedures related to the - collection, use, and storage of personal information from our users. + <> + Privacy Policy - Life and Lineage | Michael Freno + +
+
Life and Lineage's Privacy Policy
+
Last Updated: October 22, 2024
+
+ Welcome to Life and Lineage ('We', 'Us', + 'Our'). Your privacy is important to us. This privacy policy + will help you understand our policies and procedures related to the + collection, use, and storage of personal information from our users. +
+
    +
    +
    + 1. Personal Information +
    +
    +
    +
    (a) Collection of Personal Data:
    Life + and Lineage collects and stores personal data only if users opt + to use the remote saving feature. The information collected + includes email address, and if using an OAuth provider - first + name, and last name. This information is used solely for the + purpose of providing and managing the remote saving feature. It + is and never will be shared with a third party. +
    +
    +
    (b) Data Removal:
    Users can request the + removal of all information related to them by visiting{" "} + + this page + {" "} + and filling out the provided form. +
    +
    +
    + +
    +
    + 2. Third-Party Access +
    +
    +
    (a) Limited Third-Party Access:
    We do not + share or sell user information to third parties. However, we do + utilize third-party services for crash reporting and performance + profiling. These services do not have access to personal user + information and only receive anonymized data related to app + performance and stability. +
    +
    + +
    +
    + 3. Security +
    +
    +
    (a) Data Protection:
    Life and Lineage + takes appropriate measures to protect the personal information of + users who opt for the remote saving feature. We implement + industry-standard security protocols to prevent unauthorized + access, disclosure, alteration, or destruction of user data. +
    +
    + +
    +
    + 4. Changes to the Privacy Policy +
    +
    +
    (a) Updates:
    We may update this privacy + policy periodically. Any changes to this privacy policy will be + posted on this page. We encourage users to review this policy + regularly to stay informed about how we protect their information. +
    +
    + +
    +
    + 5. Contact Us +
    +
    +
    (a) Reaching Out:
    If there are any + questions or comments regarding this privacy policy, you can + contact us{" "} + + here + + . +
    +
    +
-
    -
    -
    - 1. Personal Information -
    -
    -
    -
    (a) Collection of Personal Data:
    Life and - Lineage collects and stores personal data only if users opt to use - the remote saving feature. The information collected includes - email address, and if using an OAuth provider - first name, and - last name. This information is used solely for the purpose of - providing and managing the remote saving feature. It is and never - will be shared with a third party. -
    -
    -
    (b) Data Removal:
    Users can request the - removal of all information related to them by visiting{" "} - - this page - {" "} - and filling out the provided form. -
    -
    -
    - -
    -
    - 2. Third-Party Access -
    -
    -
    (a) Limited Third-Party Access:
    We do not - share or sell user information to third parties. However, we do - utilize third-party services for crash reporting and performance - profiling. These services do not have access to personal user - information and only receive anonymized data related to app - performance and stability. -
    -
    - -
    -
    - 3. Security -
    -
    -
    (a) Data Protection:
    Life and Lineage takes - appropriate measures to protect the personal information of users - who opt for the remote saving feature. We implement - industry-standard security protocols to prevent unauthorized access, - disclosure, alteration, or destruction of user data. -
    -
    - -
    -
    - 4. Changes to the Privacy Policy -
    -
    -
    (a) Updates:
    We may update this privacy - policy periodically. Any changes to this privacy policy will be - posted on this page. We encourage users to review this policy - regularly to stay informed about how we protect their information. -
    -
    - -
    -
    - 5. Contact Us -
    -
    -
    (a) Reaching Out:
    If there are any - questions or comments regarding this privacy policy, you can contact - us{" "} - - here - - . -
    -
    -
-
+ ); } diff --git a/src/routes/privacy-policy/shapes-with-abigail.tsx b/src/routes/privacy-policy/shapes-with-abigail.tsx index c60a549..41d82da 100644 --- a/src/routes/privacy-policy/shapes-with-abigail.tsx +++ b/src/routes/privacy-policy/shapes-with-abigail.tsx @@ -1,98 +1,103 @@ import { A } from "@solidjs/router"; +import { Title, Meta } from "@solidjs/meta"; export default function PrivacyPolicy() { return ( -
-
-
- Shapes with Abigail!'s Privacy Policy -
-
Last Updated: December 21, 2023
-
- Welcome to Shapes with Abigail! ('We' , 'Us', - 'Our'). Your privacy is important to us. For that reason, - our app, "Shapes with Abigail!" has been designed to - provide our users with a secure environment. This privacy policy - will help you understand our policies and procedures related to the - non-collection, non-use, and non-storage of personal information - from our users. -
-
    + <> + Privacy Policy - Shapes with Abigail | Michael Freno + +
    +
    +
    + Shapes with Abigail!'s Privacy Policy +
    +
    Last Updated: December 21, 2023
    -
    - 1. Personal Information -
    -
    -
    -
    - (a) Non-Collection of Personal Data: -
    {" "} - Shapes with Abigail! does not collect nor store personal data. - We respect the privacy of our users, especially considering - the age of our users. We believe that no information, whether - private or personal, should be required for children to enjoy - our fun and educational app. + Welcome to Shapes with Abigail! ('We' , 'Us', + 'Our'). Your privacy is important to us. For that reason, + our app, "Shapes with Abigail!" has been designed to + provide our users with a secure environment. This privacy policy + will help you understand our policies and procedures related to the + non-collection, non-use, and non-storage of personal information + from our users. +
    +
      +
      +
      + 1. Personal Information +
      +
      +
      +
      (a) Non-Collection of Personal Data:
      {" "} + Shapes with Abigail! does not collect nor store personal data. + We respect the privacy of our users, especially considering + the age of our users. We believe that no information, whether + private or personal, should be required for children to enjoy + our fun and educational app. +
      -
    -
    -
    - 2. Third-Party Access +
    +
    + 2. Third-Party Access +
    +
    +
    (a) No Third-Party Access:
    Since we do + not collect or store any user data, there is no possibility of + sharing or selling our users' information to third parties. + Our priority is the safety and privacy of our users. +
    -
    -
    (a) No Third-Party Access:
    Since we - do not collect or store any user data, there is no possibility - of sharing or selling our users' information to third - parties. Our priority is the safety and privacy of our users. -
    -
    -
    -
    - 3. Security +
    +
    + 3. Security +
    +
    +
    (a) Secure Environment:
    Shapes with + Abigail! offers a secure and safe platform for children to play + and learn. Not requiring any personal data naturally enhances + security by eliminating potential risks related to data breaches + and misuse of information. +
    -
    -
    (a) Secure Environment:
    Shapes with - Abigail! offers a secure and safe platform for children to play - and learn. Not requiring any personal data naturally enhances - security by eliminating potential risks related to data breaches - and misuse of information. -
    -
    -
    -
    - 4. Changes to the Privacy - Policy +
    +
    + 4. Changes to the Privacy Policy +
    +
    +
    (a) Updates:
    We may update this privacy + policy periodically. Any changes to this privacy policy will be + posted on this page. However, since we do not collect any + personal data, these updates are likely to be insignificant. +
    -
    -
    (a) Updates:
    We may update this - privacy policy periodically. Any changes to this privacy policy - will be posted on this page. However, since we do not collect - any personal data, these updates are likely to be insignificant. -
    -
    -
    -
    - 5. Contact Us +
    +
    + 5. Contact Us +
    +
    +
    (a) Reaching Out:
    If there are any + questions or comments regarding this privacy policy, you can + contact us{" "} + + here + + . +
    -
    -
    (a) Reaching Out:
    If there are any - questions or comments regarding this privacy policy, you can - contact us{" "} - - here - - . -
    -
    -
+ +
-
+ ); } diff --git a/src/routes/resume.tsx b/src/routes/resume.tsx index 73e4d0e..8927e13 100644 --- a/src/routes/resume.tsx +++ b/src/routes/resume.tsx @@ -1,16 +1,24 @@ -import { Title } from "@solidjs/meta"; +import { Title, Meta } from "@solidjs/meta"; export default function Resume() { return ( -
- Resume - Freno.dev -
-