Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Q-210: add Redirect by language component #190

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@
"TabsFullContent": "TabsFullContent",
"TabsFullHead": "TabsFullHead",
"Marquee": "Marquee",
"ImageViewer": "ImageViewer"
"ImageViewer": "ImageViewer",
"Redirect": "Redirect",
"RedirectByLanguage": "RedirectByLanguage"
}
},
"quarklyInfoDeleted": {
Expand Down
69 changes: 69 additions & 0 deletions preview/docs/Redirect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
## 📖 Detailed overview

Redirect to internal or external URL.

## ⚙️ Usage

Add the component to the page, set `Destination` and check how it works in the preview mode.

> Redirect to external destination will work only on published site

### Redirect from your component

Use hook `useNavigate`:

```jsx
...
import { useNavigate } from './QuarklycommunityKitRedirect';

const Component = () => {
const navigate = useNavigate();

const onClick = () => {
navigate('/foo')
// OR
navigate('https://example.com')
}

...
}
```

## 🧩 Components and Props

### In the interface

| Prop name | Default | Example |
| :---------- | :-----: | :-------------------: |
| Destination | `-` | `https://example.com` |

### In the code (for developers)

| Prop name | Name in the code | Type | Default | Example |
| :---------- | :--------------: | :------: | :-----: | :-------------------: |
| Destination | `destination` | `string` | `-` | `https://example.com` |

## 🗄 GitHub

[Link to GitHub](https://github.com/quarkly/community-kit/blob/master/src/Redirect)

## 🗓 Changelog

- 11/08/2023 (v1.0)
- First version

## 📮 Feedback

If you encountered a bug, please contact us so we can fix it promptly. We’re developing all the time, so don’t hesitate to send us your feedback and request new features you would like to see added. Feel free to share what you’re working on - we'd **love** to see what you’re building with Quarkly!

[Help with components](https://community.quarkly.io/c/requests/11)

[We're on Discord](https://discord.gg/SuF9vCMJGW)

[Our Twitter](https://twitter.com/quarklyapp)

[[email protected]](mailto:[email protected])

## 📝 License

Licensed under the [MIT License](https://raw.githubusercontent.com/quarkly/community-kit/master/LICENSE).
50 changes: 50 additions & 0 deletions preview/docs/RedirectByLanguage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## 📖 Detailed overview

Redirect users based on browser language to internal or external URL.

## ⚙️ Usage

Add the component to the page, set `Destination` and `Languages` and check how it works in the preview mode.

> Redirect to external destination will work only on published site

## 🧩 Components and Props

### In the interface

| Prop name | Default | Example |
| :---------- | :-----: | :-------------------: |
| Destination | `-` | `https://example.com` |
| Languages | `[]` | `[en, de]` |

### In the code (for developers)

| Prop name | Name in the code | Type | Default | Example |
| :---------- | :--------------: | :------: | :-----: | :-------------------: |
| Destination | `destination` | `string` | `-` | `https://example.com` |
| Languages | `languages` | `string` | `-` | `en,de` |

## 🗄 GitHub

[Link to GitHub](https://github.com/quarkly/community-kit/blob/master/src/RedirectByLanguage)

## 🗓 Changelog

- 11/08/2023 (v1.0)
- First version

## 📮 Feedback

If you encountered a bug, please contact us so we can fix it promptly. We’re developing all the time, so don’t hesitate to send us your feedback and request new features you would like to see added. Feel free to share what you’re working on - we'd **love** to see what you’re building with Quarkly!

[Help with components](https://community.quarkly.io/c/requests/11)

[We're on Discord](https://discord.gg/SuF9vCMJGW)

[Our Twitter](https://twitter.com/quarklyapp)

[[email protected]](mailto:[email protected])

## 📝 License

Licensed under the [MIT License](https://raw.githubusercontent.com/quarkly/community-kit/master/LICENSE).
69 changes: 69 additions & 0 deletions preview/docs/ru/Redirect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
## 📖 Подробный обзор

Перенаправление на внутренний или внешний URL.

## ⚙️ Использование

Добавьте компонент на страницу, установите `Конечный URL-адрес` и проверьте, как он работает в режиме превью.

> Перенаправление на внешний URL будет работать только на опубликованном сайте

### Перенаправление из вашего компонента

Используйте хук `useNavigate`:

```jsx
...
import { useNavigate } from './QuarklycommunityKitRedirect';

const Component = () => {
const navigate = useNavigate();

const onClick = () => {
navigate('/foo')
// ИЛИ
navigate('https://example.com')
}

...
}
```

## 🧩 Компоненты и свойства

### В интерфейсе

| Названия свойств | По умолчанию | Пример |
| :----------------- | :----------: | :-------------------: |
| Конечный URL-адрес | `-` | `https://example.com` |

### В коде (для разработчиков)

| Названия свойств | Название в коде | Тип | По умолчанию | Пример |
| :----------------- | :-------------: | :------: | :----------: | :-------------------: |
| Конечный URL-адрес | `destination` | `string` | `-` | `https://example.com` |

## 🗄 GitHub

[Ссылка на GitHub](https://github.com/quarkly/community-kit/blob/master/src/Redirect)

## 🗓 Changelog

- 11/08/2023 (v1.0)
- Первая версия

## 📮 Feedback

If you encountered a bug, please contact us so we can fix it promptly. We’re developing all the time, so don’t hesitate to send us your feedback and request new features you would like to see added. Feel free to share what you’re working on - we'd **love** to see what you’re building with Quarkly!

[Help with components](https://community.quarkly.io/c/requests/11)

[We're on Discord](https://discord.gg/SuF9vCMJGW)

[Our Twitter](https://twitter.com/quarklyapp)

[[email protected]](mailto:[email protected])

## 📝 License

Licensed under the [MIT License](https://raw.githubusercontent.com/quarkly/community-kit/master/LICENSE).
50 changes: 50 additions & 0 deletions preview/docs/ru/RedirectByLanguage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## 📖 Подробный обзор

Перенаправление в зависимости от языка браузера на внутренний или внешний URL.

## ⚙️ Использование

Добавьте компонент на страницу, установите `Конечный URL-адрес`, `Языки` и проверьте, как он работает в режиме превью.

> Перенаправление на внешний URL будет работать только на опубликованном сайте

## 🧩 Компоненты и свойства

### В интерфейсе

| Названия свойств | По умолчанию | Пример |
| :----------------- | :----------: | :-------------------: |
| Конечный URL-адрес | `-` | `https://example.com` |
| Языки | `[]` | `[en, de]` |

### В коде (для разработчиков)

| Названия свойств | Название в коде | Тип | По умолчанию | Пример |
| :----------------- | :-------------: | :------: | :----------: | :-------------------: |
| Конечный URL-адрес | `destination` | `string` | `-` | `https://example.com` |
| Языки | `languages` | `string` | `-` | `en,de` |

## 🗄 GitHub

[Ссылка на GitHub](https://github.com/quarkly/community-kit/blob/master/src/RedirectByLanguages)

## 🗓 Changelog

- 11/08/2023 (v1.0)
- Первая версия

## 📮 Feedback

If you encountered a bug, please contact us so we can fix it promptly. We’re developing all the time, so don’t hesitate to send us your feedback and request new features you would like to see added. Feel free to share what you’re working on - we'd **love** to see what you’re building with Quarkly!

[Help with components](https://community.quarkly.io/c/requests/11)

[We're on Discord](https://discord.gg/SuF9vCMJGW)

[Our Twitter](https://twitter.com/quarklyapp)

[[email protected]](mailto:[email protected])

## 📝 License

Licensed under the [MIT License](https://raw.githubusercontent.com/quarkly/community-kit/master/LICENSE).
Binary file added preview/static/Redirect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added preview/static/RedirectByLanguage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions src/Redirect/Redirect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { useEffect } from 'react';
import { Box } from '@quarkly/widgets';
import { useNavigate } from './navigate';
import { propInfo, defaultProps } from './props';

const Redirect = ({ destination, ...props }) => {
const navigate = useNavigate();

useEffect(() => {
navigate(destination);
}, [navigate, destination]);

return <Box {...props}>Redirect to {destination}...</Box>;
};

Object.assign(Redirect, {
propInfo,
defaultProps,
});

export default Redirect;
2 changes: 2 additions & 0 deletions src/Redirect/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { useNavigate, useLocation } from './navigate';
export { default } from './Redirect';
97 changes: 97 additions & 0 deletions src/Redirect/navigate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { useCallback, useEffect, useState } from 'react';
import { useHistory, useLocation as useCRALocation } from 'react-router-dom';
import { navigate as gatsbyNavigate } from 'gatsby-link';
import { useLocation as useGatsbyLocation } from '@reach/router';
import { getAPI } from '../utils';

function checkDomain(url) {
if (url.indexOf('//') === 0) {
url = window.location.protocol + url;
}
return url
.toLowerCase()
.replace(/([a-z])?:\/\//, '$1')
.split('/')[0];
}

// https://stackoverflow.com/a/28054735
function isExternal(url) {
return (
(url.indexOf(':') > -1 || url.indexOf('//') > -1) &&
checkDomain(window.location.href) !== checkDomain(url)
);
}

export const useNavigate = () => {
const { projectType, mode } = getAPI() || {};
if (mode === 'development') return useQuarklyPreviewNavigate(); // eslint-disable-line react-hooks/rules-of-hooks
return projectType === 'gatsby' ? useGatsbyNavigate() : useCRANavigate(); // eslint-disable-line react-hooks/rules-of-hooks
};

export const useLocation = () => {
const { projectType, mode } = getAPI() || {};
if (mode === 'development') return useQuarklyPreviewLocation(); // eslint-disable-line react-hooks/rules-of-hooks
return projectType === 'gatsby' ? useGatsbyLocation() : useCRALocation(); // eslint-disable-line react-hooks/rules-of-hooks
};

function externalRedirect(dest) {
window.location.redirect(dest);
}

const useQuarklyPreviewNavigate = () => {
return useCallback((dest) => {
if (isExternal(dest)) return;
window.location.hash = `#${dest}`;
}, []);
};

const useCRANavigate = () => {
const history = useHistory();
return useCallback(
(dest) => {
if (isExternal(dest)) return externalRedirect(dest);
history.push(dest);
},
[history]
);
};

const useGatsbyNavigate = () => {
return useCallback((dest) => {
gatsbyNavigate(dest);
}, []);
};

const isBrowser = typeof window !== 'undefined';

const getCurrentLocation = () => {
if (!isBrowser)
return {
pathname: '',
hash: '',
search: '',
};

const pathname = window.location.hash.slice(1);
const possibleHash = pathname.split('#')[1] ?? '';
return {
pathname,
hash: possibleHash ? `#${possibleHash}` : possibleHash,
search: window.location.search,
};
};

const useQuarklyPreviewLocation = () => {
const [location, setLocation] = useState(getCurrentLocation());

useEffect(() => {
window.addEventListener('popstate', handleChange);
return () => window.removeEventListener('popstate', handleChange);
}, []);

function handleChange() {
setLocation(getCurrentLocation());
}

return location;
};
2 changes: 2 additions & 0 deletions src/Redirect/props/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as propInfo } from './propsInfo';
export { default as defaultProps } from './propsDefault';
3 changes: 3 additions & 0 deletions src/Redirect/props/propsDefault.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
destination: '',
};
10 changes: 10 additions & 0 deletions src/Redirect/props/propsInfo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default {
destination: {
title: {
en: 'Destination',
ru: 'Конечный URL-адрес',
},
control: 'href',
weight: 1,
},
};
Loading
Loading