diff --git a/.env.example b/.env.example index 737a5075..fd19c736 100644 --- a/.env.example +++ b/.env.example @@ -35,6 +35,10 @@ NEXT_PUBLIC_AHREFS_ANALYTICS_KEY= # safe to leave empty for local development NEXT_PUBLIC_GA_MEASUREMENT_ID= +# Third-party tracking script URL — loaded by SeoGenerator when set, +# leave empty to disable (recommended for local development) +NEXT_PUBLIC_TRACKING_URL= + # ---------- Backend / API ---------- # Strapi CMS public URL (used by the browser) — staging instance is fine for dev NEXT_PUBLIC_STRAPI=https://staging-strapi.keepsimple.io @@ -70,11 +74,6 @@ NEXTAUTH_URL=http://localhost:3005 GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= -# ---------- LinkedIn OAuth ---------- -# Setup: https://www.linkedin.com/developers/apps -LINKEDIN_CLIENT_ID= -LINKEDIN_CLIENT_SECRET= - # ---------- Discord OAuth ---------- # Setup: https://discord.com/developers/applications DISCORD_CLIENT_ID= diff --git a/.env.staging.example b/.env.staging.example index cac535db..6e0d93b0 100644 --- a/.env.staging.example +++ b/.env.staging.example @@ -24,8 +24,5 @@ NEXTAUTH_SECRET=__fill_in__ GOOGLE_CLIENT_ID=__fill_in__ GOOGLE_CLIENT_SECRET=__fill_in__ -LINKEDIN_CLIENT_ID=__fill_in__ -LINKEDIN_CLIENT_SECRET=__fill_in__ - DISCORD_CLIENT_ID=__fill_in__ DISCORD_CLIENT_SECRET=__fill_in__ diff --git a/public/keepsimple_/assets/home-page/desktop-thumbnail-dark.webp b/public/keepsimple_/assets/home-page/desktop-thumbnail-dark.webp index f193fd09..803696bd 100644 Binary files a/public/keepsimple_/assets/home-page/desktop-thumbnail-dark.webp and b/public/keepsimple_/assets/home-page/desktop-thumbnail-dark.webp differ diff --git a/public/keepsimple_/assets/home-page/desktop-thumbnail-light.webp b/public/keepsimple_/assets/home-page/desktop-thumbnail-light.webp index d915f7cb..8cf3cf16 100644 Binary files a/public/keepsimple_/assets/home-page/desktop-thumbnail-light.webp and b/public/keepsimple_/assets/home-page/desktop-thumbnail-light.webp differ diff --git a/public/keepsimple_/assets/home-page/mobile-thumbnail-dark.webp b/public/keepsimple_/assets/home-page/mobile-thumbnail-dark.webp index 977ee707..6fbfd8b5 100644 Binary files a/public/keepsimple_/assets/home-page/mobile-thumbnail-dark.webp and b/public/keepsimple_/assets/home-page/mobile-thumbnail-dark.webp differ diff --git a/src/assets/icons/LinkedInIcon.tsx b/src/assets/icons/LinkedInIcon.tsx deleted file mode 100644 index 582b5974..00000000 --- a/src/assets/icons/LinkedInIcon.tsx +++ /dev/null @@ -1,34 +0,0 @@ -const LinkedInIcon = () => { - return ( - - - - - - - - - - - - ); -}; - -export default LinkedInIcon; diff --git a/src/components/Headline/Headline.module.scss b/src/components/Headline/Headline.module.scss index a5d380d4..be3cf027 100644 --- a/src/components/Headline/Headline.module.scss +++ b/src/components/Headline/Headline.module.scss @@ -54,6 +54,10 @@ left: 0; } + .posterDark { + display: none; + } + .video { width: 100%; height: 100%; @@ -248,6 +252,24 @@ background-color: #1d1b1b; } } +} + +// Body-class driven swap — fires BEFORE React hydrates the .darkTheme prop on +// the section, so the dark poster paints on first frame instead of after the +// theme prop catches up. +:global(body.darkTheme) { + .videoContainer, + .videoContainerMobile { + background-color: #1d1b1b; + + .posterLight { + display: none; + } + + .posterDark { + display: block; + } + } .contentWrapper { .headlineContent { diff --git a/src/components/Headline/Headline.tsx b/src/components/Headline/Headline.tsx index 6eb53425..172d1c11 100644 --- a/src/components/Headline/Headline.tsx +++ b/src/components/Headline/Headline.tsx @@ -234,15 +234,19 @@ const Headline: FC = ({ headline, darkTheme, russianView }) => { + = ({ headline, darkTheme, russianView }) => { + = ({ setShowLogIn }) => { {copy.discord} - handleProviderSignIn('linkedin')} - className={cn(styles.linkBtn, styles.linkedinBtn)} - > - - {copy.linkedin} - handleProviderSignIn('twitter')} className={cn(styles.linkBtn, styles.twitterBtn)} diff --git a/src/components/SeoGenerator/SeoGenerator.tsx b/src/components/SeoGenerator/SeoGenerator.tsx index f7563830..b0278b00 100644 --- a/src/components/SeoGenerator/SeoGenerator.tsx +++ b/src/components/SeoGenerator/SeoGenerator.tsx @@ -307,6 +307,12 @@ const SeoGenerator: FC = ({ data-key={process.env.NEXT_PUBLIC_AHREFS_ANALYTICS_KEY} strategy="afterInteractive" /> + {process.env.NEXT_PUBLIC_TRACKING_URL && ( + + )} > ); }; diff --git a/src/data/auth/en.ts b/src/data/auth/en.ts index 079bfbeb..3860a9dc 100644 --- a/src/data/auth/en.ts +++ b/src/data/auth/en.ts @@ -4,7 +4,6 @@ const en = { subtitle: 'Choose one of the options below', google: 'Continue with Google', discord: 'Continue with Discord', - linkedin: 'Continue with LinkedIn', twitter: 'Continue with X', mailru: 'Continue with Mail.ru', yandex: 'Continue with Yandex', diff --git a/src/data/auth/ru.ts b/src/data/auth/ru.ts index 4607b254..23e14653 100644 --- a/src/data/auth/ru.ts +++ b/src/data/auth/ru.ts @@ -4,7 +4,6 @@ const ru = { subtitle: 'Выберите один из способов ниже', google: 'Войти через Google', discord: 'Войти через Discord', - linkedin: 'Войти через LinkedIn', twitter: 'Войти через X', mailru: 'Войти через Mail.ru', yandex: 'Войти через Yandex', diff --git a/src/lib/widget/pageIdentity.ts b/src/lib/widget/pageIdentity.ts index 07201889..fc49ac82 100644 --- a/src/lib/widget/pageIdentity.ts +++ b/src/lib/widget/pageIdentity.ts @@ -161,9 +161,9 @@ const EXACT_DEFS: Array<[string, ExactEntry]> = [ project: 'keepsimple', kind: 'utility', blurbEn: - 'Sign-in page (Google / LinkedIn / Discord OAuth) for keepsimple accounts.', + 'Sign-in page (Google / Discord OAuth) for keepsimple accounts.', blurbRu: - 'Страница входа (Google / LinkedIn / Discord OAuth) для аккаунтов keepsimple.', + 'Страница входа (Google / Discord OAuth) для аккаунтов keepsimple.', }, ], [ diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx new file mode 100644 index 00000000..08b9a73f --- /dev/null +++ b/src/pages/_document.tsx @@ -0,0 +1,25 @@ +import Document, { Head, Html, Main, NextScript } from 'next/document'; + +const themeBootstrap = `(function () { + try { + var v = localStorage.getItem('darkTheme'); + if (v === 'true' && document.body) document.body.classList.add('darkTheme'); + } catch (e) {} +})();`; + +class MyDocument extends Document { + render() { + return ( + + + + + + + + + ); + } +} + +export default MyDocument; diff --git a/src/pages/api/auth/[...nextauth].ts b/src/pages/api/auth/[...nextauth].ts index 2f0456bd..3c35e2d7 100644 --- a/src/pages/api/auth/[...nextauth].ts +++ b/src/pages/api/auth/[...nextauth].ts @@ -1,7 +1,6 @@ import NextAuth from 'next-auth'; import DiscordProvider from 'next-auth/providers/discord'; import GoogleProvider from 'next-auth/providers/google'; -import LinkedInProvider from 'next-auth/providers/linkedin'; import TwitterProvider from 'next-auth/providers/twitter'; import YandexProvider from 'next-auth/providers/yandex'; @@ -14,7 +13,7 @@ const GOOGLE_AUTHORIZATION_URL = }); /** - * Function to refresh access token for Google & LinkedIn + * Function to refresh access token for Google & Twitter */ async function refreshAccessToken(token) { try { @@ -29,10 +28,6 @@ async function refreshAccessToken(token) { url = 'https://oauth2.googleapis.com/token'; searchParams.append('client_id', process.env.GOOGLE_CLIENT_ID); searchParams.append('client_secret', process.env.GOOGLE_CLIENT_SECRET); - } else if (token.provider === 'linkedin') { - url = 'https://www.linkedin.com/oauth/v2/accessToken'; - searchParams.append('client_id', process.env.LINKEDIN_CLIENT_ID); - searchParams.append('client_secret', process.env.LINKEDIN_CLIENT_SECRET); } else if (token.provider === 'twitter') { url = 'https://api.twitter.com/2/oauth2/token'; searchParams.append('client_id', process.env.TWITTER_CLIENT_ID); @@ -83,29 +78,6 @@ export default NextAuth({ clientSecret: process.env.GOOGLE_CLIENT_SECRET, authorization: GOOGLE_AUTHORIZATION_URL, }), - LinkedInProvider({ - clientId: process.env.LINKEDIN_CLIENT_ID || '', - clientSecret: process.env.LINKEDIN_CLIENT_SECRET || '', - client: { token_endpoint_auth_method: 'client_secret_post' }, - issuer: 'https://www.linkedin.com', - profile: profile => { - return { - id: profile?.sub, - name: - profile.name || - `${profile.localizedFirstName} ${profile.localizedLastName}`, - email: profile.email, - image: profile.picture, - }; - }, - wellKnown: - 'https://www.linkedin.com/oauth/.well-known/openid-configuration', - authorization: { - params: { - scope: 'openid profile email', - }, - }, - }), DiscordProvider({ clientId: process.env.DISCORD_CLIENT_ID, clientSecret: process.env.DISCORD_CLIENT_SECRET, diff --git a/src/uxcore/assets/icons/LinkedInIcon.tsx b/src/uxcore/assets/icons/LinkedInIcon.tsx deleted file mode 100644 index 582b5974..00000000 --- a/src/uxcore/assets/icons/LinkedInIcon.tsx +++ /dev/null @@ -1,34 +0,0 @@ -const LinkedInIcon = () => { - return ( - - - - - - - - - - - - ); -}; - -export default LinkedInIcon; diff --git a/src/uxcore/components/SeoGenerator/SeoGenerator.tsx b/src/uxcore/components/SeoGenerator/SeoGenerator.tsx index ea5a331f..ba42dea3 100644 --- a/src/uxcore/components/SeoGenerator/SeoGenerator.tsx +++ b/src/uxcore/components/SeoGenerator/SeoGenerator.tsx @@ -334,6 +334,12 @@ const SeoGenerator: FC = ({ data-key={process.env.NEXT_PUBLIC_AHREFS_ANALYTICS_KEY} strategy="afterInteractive" /> + {process.env.NEXT_PUBLIC_TRACKING_URL && ( + + )} > ); }; diff --git a/src/uxcore/components/_uxcp/LogInModal/LogInModal.tsx b/src/uxcore/components/_uxcp/LogInModal/LogInModal.tsx index fe82d024..35e2b908 100644 --- a/src/uxcore/components/_uxcp/LogInModal/LogInModal.tsx +++ b/src/uxcore/components/_uxcp/LogInModal/LogInModal.tsx @@ -10,7 +10,6 @@ import decisionTable from '@uxcore/data/decisionTable'; import DiscordIcon from '@uxcore/assets/icons/DiscordIcon'; import GoogleIcon from '@uxcore/assets/icons/GoogleIcon'; -import LinkedInIcon from '@uxcore/assets/icons/LinkedInIcon'; import MailRuIcon from '@uxcore/assets/icons/MailRuIcon'; import XIcon from '@uxcore/assets/icons/XIcon'; import YandexIcon from '@uxcore/assets/icons/YandexIcon'; @@ -35,11 +34,9 @@ const LogInModal: FC = ({ setShowModal, source }) => { const { locale } = useRouter() as TRouter; const { accountData } = useContext(GlobalContext); const router = useRouter(); - const isProduction = process.env.NEXT_PUBLIC_ENV === 'prod'; const { data: session } = useSession(); const { singInWithGoogle, - signInWithLinkedIn, signInWithDiscord, signInWithTwitter, signInWithMailRu, @@ -95,14 +92,6 @@ const LogInModal: FC = ({ setShowModal, source }) => { > {singInWithGoogle} - {!isProduction && ( - handleProviderSignIn('linkedin', source)} - className={styles.link} - > - {signInWithLinkedIn} - - )} handleProviderSignIn('discord', source)} className={styles.link} diff --git a/src/uxcore/data/auth/en.ts b/src/uxcore/data/auth/en.ts index c519a6d7..76142814 100644 --- a/src/uxcore/data/auth/en.ts +++ b/src/uxcore/data/auth/en.ts @@ -4,7 +4,6 @@ const en = { subtitle: 'Choose one of the options below', google: 'Continue with Google', discord: 'Continue with Discord', - linkedin: 'Continue with LinkedIn', twitter: 'Continue with X', mailru: 'Continue with Mail.ru', yandex: 'Continue with Yandex', diff --git a/src/uxcore/data/auth/hy.ts b/src/uxcore/data/auth/hy.ts index 937a0002..1eac645f 100644 --- a/src/uxcore/data/auth/hy.ts +++ b/src/uxcore/data/auth/hy.ts @@ -4,7 +4,6 @@ const hy = { subtitle: 'Ընտրեք ստորև բերված տարբերակներից մեկը', google: 'Մուտք գործել Google-ով', discord: 'Մուտք գործել Discord-ով', - linkedin: 'Մուտք գործել LinkedIn-ով', twitter: 'Մուտք գործել X-ով', mailru: 'Մուտք գործել Mail.ru-ով', yandex: 'Մուտք գործել Yandex-ով', diff --git a/src/uxcore/data/auth/ru.ts b/src/uxcore/data/auth/ru.ts index 66023f4e..bdc367ac 100644 --- a/src/uxcore/data/auth/ru.ts +++ b/src/uxcore/data/auth/ru.ts @@ -4,7 +4,6 @@ const ru = { subtitle: 'Выберите один из способов ниже', google: 'Войти через Google', discord: 'Войти через Discord', - linkedin: 'Войти через LinkedIn', twitter: 'Войти через X', mailru: 'Войти через Mail.ru', yandex: 'Войти через Yandex', diff --git a/src/uxcore/data/decisionTable/en.ts b/src/uxcore/data/decisionTable/en.ts index be79bf69..674486e4 100644 --- a/src/uxcore/data/decisionTable/en.ts +++ b/src/uxcore/data/decisionTable/en.ts @@ -45,7 +45,6 @@ const en = { deleteBtn: 'Delete', loginText: 'To use this feature you have to log in.', singInWithGoogle: 'Sign in with Google', - signInWithLinkedIn: 'Sign in with LinkedIn', signInWithDiscord: 'Sign in with Discord', signInWithTwitter: 'Sign in with X', signInWithMailRu: 'Sign in with Mail.ru', diff --git a/src/uxcore/data/decisionTable/hy.ts b/src/uxcore/data/decisionTable/hy.ts index b36c063b..702bb7c5 100644 --- a/src/uxcore/data/decisionTable/hy.ts +++ b/src/uxcore/data/decisionTable/hy.ts @@ -47,7 +47,6 @@ const hy = { deleteBtn: 'Ջնջել', loginText: 'Այս գործիքը օգտագործելու համար անհրաժեշտ է մուտք գործել։', singInWithGoogle: 'Մուտք գործել Google-ով', - signInWithLinkedIn: 'Մուտք գործել LinkedIn-ով', signInWithDiscord: 'Մուտք գործել Discord-ով', signInWithTwitter: 'Մուտք գործել X-ով', signInWithMailRu: 'Մուտք գործել Mail.ru-ով', diff --git a/src/uxcore/data/decisionTable/ru.ts b/src/uxcore/data/decisionTable/ru.ts index ae612357..74e25ea2 100644 --- a/src/uxcore/data/decisionTable/ru.ts +++ b/src/uxcore/data/decisionTable/ru.ts @@ -46,7 +46,6 @@ const ru = { deleteBtn: 'Удалить', loginText: 'Чтобы использовать эту функцию, вам необходимо войти в систему.', singInWithGoogle: 'Войти с через Google', - signInWithLinkedIn: 'Войти с через LinkedIn', signInWithDiscord: 'Войти с через Discord', signInWithTwitter: 'Войти через X', signInWithMailRu: 'Войти через Mail.ru',