mirror of
https://github.com/astuto/astuto.git
synced 2025-12-16 19:57:52 +01:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9176b96167 | ||
|
|
d85bce76ad | ||
|
|
fb5e6165c3 |
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@@ -1 +0,0 @@
|
|||||||
github: riggraz
|
|
||||||
44
README.md
44
README.md
@@ -1,23 +1,13 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://astuto.io/?utm_campaign=github_logo&utm_source=github.com">
|
|
||||||
<img width="400" src="./images/logo-and-name.png" />
|
<img width="400" src="./images/logo-and-name.png" />
|
||||||
</a>
|
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://www.producthunt.com/posts/astuto?utm_source=badge-top-post-badge&utm_medium=badge&utm_souce=badge-astuto" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=179870&theme=neutral&period=daily" alt="Astuto - An open source customer feedback tool 🦊 | Product Hunt Embed" style="width: 250px; height: 54px;" width="250px" height="54px" /></a>
|
<a href="https://www.producthunt.com/posts/astuto?utm_source=badge-top-post-badge&utm_medium=badge&utm_souce=badge-astuto" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=179870&theme=neutral&period=daily" alt="Astuto - An open source customer feedback tool 🦊 | Product Hunt Embed" style="width: 250px; height: 54px;" width="250px" height="54px" /></a>
|
||||||
<br>
|
|
||||||
<h3 align="center">
|
|
||||||
<a href="https://feedback.astuto.io/">✨ Try it out</a>
|
|
||||||
•
|
|
||||||
<a href="https://astuto.io/?utm_campaign=github_learnmore&utm_source=github.com">📖 Learn more</a>
|
|
||||||
</h3>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Astuto is an open source customer feedback tool. It helps you collect, manage and prioritize feedback from your customers, so you can build a better product.
|
Astuto is an open source customer feedback tool. It helps you collect, manage and prioritize feedback from your customers, so you can build a better product.
|
||||||
|
|
||||||
<a href="https://feedback.astuto.io/">
|
<img src="./images/hero-image.png" />
|
||||||
<img src="./images/hero-image.png" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -29,28 +19,12 @@ Astuto is an open source customer feedback tool. It helps you collect, manage an
|
|||||||
- **Anonymous Feedback**: enable unregistered users to publish feedback
|
- **Anonymous Feedback**: enable unregistered users to publish feedback
|
||||||
- **... and more**: invitation system, brand customization, recap emails for administrators, private site settings, and more!
|
- **... and more**: invitation system, brand customization, recap emails for administrators, private site settings, and more!
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Documentation website is not online anymore. You can read Astuto's documentation from the [GitHub repository](https://github.com/astuto/astuto-docs).
|
||||||
|
|
||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
### Hosted
|
|
||||||
|
|
||||||
We offer a hosted solution, so you don't have to provision your own server. This is the easiest and fastest way to get started: you can sign up and start collecting feedback in a few minutes.
|
|
||||||
|
|
||||||
[Start your 7-day free trial](https://login.astuto.io/signup) without entering any payment method, then it's 15 €/month with annual subscription or 20 €/month with monthly subscription. [Learn more on astuto.io](https://astuto.io/?utm_campaign=github_getstarted&utm_source=github.com).
|
|
||||||
|
|
||||||
With the paid plan:
|
|
||||||
|
|
||||||
- You avoid deployment hassles like renting a server, issuing SSL certificates, configuring a mail server and managing updates
|
|
||||||
- You get some OAuth providers out of the box: Google, Facebook and GitHub are ready to log your users in, no configuration needed
|
|
||||||
- You get priority support
|
|
||||||
- You support open source and get our eternal gratitude :)
|
|
||||||
|
|
||||||
|
|
||||||
### Self-hosted
|
|
||||||
|
|
||||||
Read the [Deploy with Docker instructions](https://docs.astuto.io/deploy-docker) for the most comprehensive and up to date guide on installing and configuring Astuto.
|
|
||||||
|
|
||||||
What you find below are minimal instructions to get you started as quickly as possible:
|
|
||||||
|
|
||||||
0. Ensure you have Docker and Docker Compose installed
|
0. Ensure you have Docker and Docker Compose installed
|
||||||
1. Create an empty folder
|
1. Create an empty folder
|
||||||
2. Inside that folder, create a `docker-compose.yml` file with the following content:
|
2. Inside that folder, create a `docker-compose.yml` file with the following content:
|
||||||
@@ -77,21 +51,17 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
dbdata:
|
dbdata:
|
||||||
```
|
```
|
||||||
3. Edit the environment variables to fit your needs. You can find more information about env variables in the [documentation](https://docs.astuto.io/deploy-docker/#2-edit-environment-variables).
|
3. Edit the environment variables to fit your needs
|
||||||
4. Run `docker compose pull && docker compose up`
|
4. Run `docker compose pull && docker compose up`
|
||||||
5. You should now have a running instance of Astuto on port 3000. A default user account has been created with credentials email: `admin@example.com`, password: `password`.
|
5. You should now have a running instance of Astuto on port 3000. A default user account has been created with credentials email: `admin@example.com`, password: `password`.
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
Check out [docs.astuto.io](https://docs.astuto.io/) to learn how to deploy Astuto, configure custom OAuth providers and webhooks, use our REST API and more!
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
There are many ways to contribute to Astuto, not just coding. Proposing features, reporting issues, translating to a new language or improving documentation are a few examples! Please read our [contributing guidelines](https://github.com/riggraz/astuto/blob/main/CONTRIBUTING.md) to learn more.
|
There are many ways to contribute to Astuto, not just coding. Proposing features, reporting issues, translating to a new language or improving documentation are a few examples! Please read our [contributing guidelines](https://github.com/riggraz/astuto/blob/main/CONTRIBUTING.md) to learn more.
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
Astuto logo and all image assets are credited [here](https://astuto.io/credits).
|
Astuto logo and all image assets are credited [here](https://github.com/astuto/astuto-io/blob/main/src/pages/Credits.jsx).
|
||||||
|
|
||||||
A huge thank you to code contributors
|
A huge thank you to code contributors
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ class TenantsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
# NOTE: new tenants registrations disabled
|
||||||
|
raise "Tenant registration disabled"
|
||||||
|
|
||||||
@tenant = Tenant.new
|
@tenant = Tenant.new
|
||||||
@tenant.assign_attributes(tenant_create_params)
|
@tenant.assign_attributes(tenant_create_params)
|
||||||
authorize @tenant
|
authorize @tenant
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ const Billing = ({
|
|||||||
<p>Subscription {isExpired ? 'expired' : 'expires'} on {subscriptionEndsAtFormatted}</p>
|
<p>Subscription {isExpired ? 'expired' : 'expires'} on {subscriptionEndsAtFormatted}</p>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{/* {
|
||||||
(tenantBilling.status === TENANT_BILLING_STATUS_TRIAL) && chosenPrice === null &&
|
(tenantBilling.status === TENANT_BILLING_STATUS_TRIAL) && chosenPrice === null &&
|
||||||
<PricingTable
|
<PricingTable
|
||||||
prices={prices}
|
prices={prices}
|
||||||
@@ -169,16 +169,20 @@ const Billing = ({
|
|||||||
You will be redirected to Stripe, our billing partner.
|
You will be redirected to Stripe, our billing partner.
|
||||||
</SmallMutedText>
|
</SmallMutedText>
|
||||||
</div>
|
</div>
|
||||||
}
|
} */}
|
||||||
|
|
||||||
<div className="billingUsefulLinks">
|
<p>
|
||||||
|
We do not accept new subscriptions right now.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* <div className="billingUsefulLinks">
|
||||||
<ActionLink onClick={() => window.open('https://astuto.io/terms-of-service', '_blank')} icon={<LearnMoreIcon />}>
|
<ActionLink onClick={() => window.open('https://astuto.io/terms-of-service', '_blank')} icon={<LearnMoreIcon />}>
|
||||||
Terms of Service
|
Terms of Service
|
||||||
</ActionLink>
|
</ActionLink>
|
||||||
<ActionLink onClick={() => window.open('https://astuto.io/privacy-policy', '_blank')} icon={<LearnMoreIcon />}>
|
<ActionLink onClick={() => window.open('https://astuto.io/privacy-policy', '_blank')} icon={<LearnMoreIcon />}>
|
||||||
Privacy Policy
|
Privacy Policy
|
||||||
</ActionLink>
|
</ActionLink>
|
||||||
</div>
|
</div> */}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ const AppearanceSiteSettingsP = ({
|
|||||||
|
|
||||||
<p style={{textAlign: 'left'}}>
|
<p style={{textAlign: 'left'}}>
|
||||||
<ActionLink
|
<ActionLink
|
||||||
onClick={() => window.open('https://docs.astuto.io/appearance-customization/', '_blank')}
|
onClick={() => window.open('https://github.com/astuto/astuto-docs/blob/main/docs/appearance.md', '_blank')}
|
||||||
icon={<LearnMoreIcon />}
|
icon={<LearnMoreIcon />}
|
||||||
>
|
>
|
||||||
{I18n.t('site_settings.appearance.learn_more')}
|
{I18n.t('site_settings.appearance.learn_more')}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ const OAuthProvidersList = ({
|
|||||||
|
|
||||||
<p style={{textAlign: 'left'}}>
|
<p style={{textAlign: 'left'}}>
|
||||||
<ActionLink
|
<ActionLink
|
||||||
onClick={() => window.open('https://docs.astuto.io/category/oauth-configuration/', '_blank')}
|
onClick={() => window.open('https://github.com/astuto/astuto-docs/blob/main/docs/oauth/oauth-configuration-basics.md', '_blank')}
|
||||||
icon={<LearnMoreIcon />}
|
icon={<LearnMoreIcon />}
|
||||||
>
|
>
|
||||||
{I18n.t('site_settings.authentication.learn_more')}
|
{I18n.t('site_settings.authentication.learn_more')}
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ const GeneralSiteSettingsP = ({
|
|||||||
}
|
}
|
||||||
<div style={{marginTop: 8}}>
|
<div style={{marginTop: 8}}>
|
||||||
<ActionLink
|
<ActionLink
|
||||||
onClick={() => window.open('https://docs.astuto.io/custom-domain', '_blank')}
|
onClick={() => window.open('https://github.com/astuto/astuto-docs/blob/main/docs/custom-domain.md', '_blank')}
|
||||||
icon={<LearnMoreIcon />}
|
icon={<LearnMoreIcon />}
|
||||||
>
|
>
|
||||||
{I18n.t('site_settings.general.custom_domain_learn_more')}
|
{I18n.t('site_settings.general.custom_domain_learn_more')}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const WebhooksIndexPage = ({
|
|||||||
|
|
||||||
<p style={{textAlign: 'left'}}>
|
<p style={{textAlign: 'left'}}>
|
||||||
<ActionLink
|
<ActionLink
|
||||||
onClick={() => window.open('https://docs.astuto.io/webhooks/webhooks-introduction/', '_blank')}
|
onClick={() => window.open('https://github.com/astuto/astuto-docs/blob/main/docs/webhooks/webhooks-introduction.md', '_blank')}
|
||||||
icon={<LearnMoreIcon />}
|
icon={<LearnMoreIcon />}
|
||||||
>
|
>
|
||||||
{I18n.t('site_settings.webhooks.learn_more')}
|
{I18n.t('site_settings.webhooks.learn_more')}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import ConfirmEmailSignUpPage from './ConfirmEmailSignUpPage';
|
|||||||
import ConfirmOAuthSignUpPage from './ConfirmOAuthSignUpPage';
|
import ConfirmOAuthSignUpPage from './ConfirmOAuthSignUpPage';
|
||||||
import { IOAuth } from '../../interfaces/IOAuth';
|
import { IOAuth } from '../../interfaces/IOAuth';
|
||||||
import HttpStatus from '../../constants/http_status';
|
import HttpStatus from '../../constants/http_status';
|
||||||
|
import Box from '../common/Box';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
oAuthLoginCompleted: boolean;
|
oAuthLoginCompleted: boolean;
|
||||||
@@ -116,57 +117,70 @@ const TenantSignUpP = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <>
|
||||||
|
// <img src={astutoLogoImage} width={64} height={64} className="astutoLogo" />
|
||||||
|
|
||||||
|
// <div className="tenantSignUpContainer">
|
||||||
|
// {
|
||||||
|
// (currentStep === 1 || currentStep === 2) &&
|
||||||
|
// <UserSignUpForm
|
||||||
|
// currentStep={currentStep}
|
||||||
|
// setCurrentStep={setCurrentStep}
|
||||||
|
// authMethod={authMethod}
|
||||||
|
// setAuthMethod={setAuthMethod}
|
||||||
|
// oAuths={oAuths}
|
||||||
|
// userData={userData}
|
||||||
|
// setUserData={setUserData}
|
||||||
|
// setGoneBack={setGoneBack}
|
||||||
|
// />
|
||||||
|
// }
|
||||||
|
|
||||||
|
// {
|
||||||
|
// (goneBack || currentStep === 2) &&
|
||||||
|
// <TenantSignUpForm
|
||||||
|
// isSubmitting={isSubmitting}
|
||||||
|
// error={error}
|
||||||
|
// handleSignUpSubmit={handleSignUpSubmit}
|
||||||
|
// trialPeriodDays={trialPeriodDays}
|
||||||
|
// currentStep={currentStep}
|
||||||
|
// setCurrentStep={setCurrentStep}
|
||||||
|
// />
|
||||||
|
// }
|
||||||
|
|
||||||
|
// {
|
||||||
|
// currentStep === 3 && authMethod === 'oauth' &&
|
||||||
|
// <ConfirmOAuthSignUpPage
|
||||||
|
// baseUrl={baseUrl}
|
||||||
|
// subdomain={tenantData.subdomain}
|
||||||
|
// feedbackSpaceCreatedImage={feedbackSpaceCreatedImage}
|
||||||
|
// />
|
||||||
|
// }
|
||||||
|
|
||||||
|
// {
|
||||||
|
// currentStep === 3 && authMethod === 'email' &&
|
||||||
|
// <ConfirmEmailSignUpPage
|
||||||
|
// subdomain={tenantData.subdomain}
|
||||||
|
// userEmail={userData.email}
|
||||||
|
// pendingTenantImage={pendingTenantImage}
|
||||||
|
// />
|
||||||
|
// }
|
||||||
|
// </div>
|
||||||
|
// </>
|
||||||
|
// );
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<img src={astutoLogoImage} width={64} height={64} className="astutoLogo" />
|
<img src={astutoLogoImage} width={64} height={64} className="astutoLogo" />
|
||||||
|
|
||||||
<div className="tenantSignUpContainer">
|
<div className="tenantSignUpContainer">
|
||||||
{
|
<Box>
|
||||||
(currentStep === 1 || currentStep === 2) &&
|
<p>It is not possible to sign up to Astuto.</p>
|
||||||
<UserSignUpForm
|
<p>You can <a href="https://github.com/astuto/astuto">self-host your own instance</a> instead.</p>
|
||||||
currentStep={currentStep}
|
</Box>
|
||||||
setCurrentStep={setCurrentStep}
|
|
||||||
authMethod={authMethod}
|
|
||||||
setAuthMethod={setAuthMethod}
|
|
||||||
oAuths={oAuths}
|
|
||||||
userData={userData}
|
|
||||||
setUserData={setUserData}
|
|
||||||
setGoneBack={setGoneBack}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
(goneBack || currentStep === 2) &&
|
|
||||||
<TenantSignUpForm
|
|
||||||
isSubmitting={isSubmitting}
|
|
||||||
error={error}
|
|
||||||
handleSignUpSubmit={handleSignUpSubmit}
|
|
||||||
trialPeriodDays={trialPeriodDays}
|
|
||||||
currentStep={currentStep}
|
|
||||||
setCurrentStep={setCurrentStep}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
currentStep === 3 && authMethod === 'oauth' &&
|
|
||||||
<ConfirmOAuthSignUpPage
|
|
||||||
baseUrl={baseUrl}
|
|
||||||
subdomain={tenantData.subdomain}
|
|
||||||
feedbackSpaceCreatedImage={feedbackSpaceCreatedImage}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
currentStep === 3 && authMethod === 'email' &&
|
|
||||||
<ConfirmEmailSignUpPage
|
|
||||||
subdomain={tenantData.subdomain}
|
|
||||||
userEmail={userData.email}
|
|
||||||
pendingTenantImage={pendingTenantImage}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TenantSignUpP;
|
export default TenantSignUpP;
|
||||||
@@ -81,14 +81,6 @@ const GenerateApiKeyDialog = ({
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
<br /><br />
|
|
||||||
<ActionLink
|
|
||||||
icon={<LearnMoreIcon />}
|
|
||||||
onClick={() => window.open('https://docs.astuto.io/api', '_blank')}
|
|
||||||
>
|
|
||||||
{I18n.t('common.forms.api_key.api_key_learn_more')}
|
|
||||||
</ActionLink>
|
|
||||||
|
|
||||||
{ error && <DangerText>{error}</DangerText> }
|
{ error && <DangerText>{error}</DangerText> }
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import I18n from 'i18n-js';
|
|||||||
|
|
||||||
const PoweredByLink = () => (
|
const PoweredByLink = () => (
|
||||||
<div className="poweredBy">
|
<div className="poweredBy">
|
||||||
<a href={`http://astuto.io/?utm_campaign=poweredby&utm_source=${window.location.hostname}`} target="_blank">
|
<a href="https://github.com/astuto/astuto/" target="_blank">
|
||||||
{ I18n.t('common.powered_by') } Astuto
|
{ I18n.t('common.powered_by') } Astuto
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
<% if not Rails.application.multi_tenancy? %>
|
<% if not Rails.application.multi_tenancy? %>
|
||||||
<p>You have to <a href="https://docs.astuto.io/deploy-with-sidekiq">enable Sidekiq</a> to receive recap notifications.</p>
|
<p>You have to <a href="https://github.com/astuto/astuto-docs/blob/main/docs/deploy/sidekiq.md">enable Sidekiq</a> to receive recap notifications.</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
<% unless @boards.empty? %>
|
<% unless @boards.empty? %>
|
||||||
<%= link_to t('header.menu.tour'), @header_full_urls ? get_url_for(method(:board_url), resource: @boards.first, options: { tour: true }) : board_path(@boards.first, tour: true), class: 'dropdown-item tourDropdown' %>
|
<%= link_to t('header.menu.tour'), @header_full_urls ? get_url_for(method(:board_url), resource: @boards.first, options: { tour: true }) : board_path(@boards.first, tour: true), class: 'dropdown-item tourDropdown' %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= link_to t('header.menu.docs'), 'https://docs.astuto.io', class: 'dropdown-item', target: '_blank' %>
|
<%= link_to t('header.menu.docs'), 'https://github.com/astuto/astuto-docs', class: 'dropdown-item', target: '_blank' %>
|
||||||
<%= link_to t('header.menu.support'), Rails.application.multi_tenancy? ? 'mailto:info@astuto.io' : 'https://github.com/astuto/astuto/issues', class: 'dropdown-item', target: '_blank' %>
|
<%= link_to t('header.menu.support'), Rails.application.multi_tenancy? ? 'mailto:info@astuto.io' : 'https://github.com/astuto/astuto/issues', class: 'dropdown-item', target: '_blank' %>
|
||||||
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Dive into your new feedback space at <a href="<%= get_url_for(method(:root_url))
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To customize your feedback space, just head to <a href="<%= get_url_for(method(:site_settings_general_url)) %>">site settings</a>. For more advanced configurations, such as custom OAuth providers or custom domains, you can refer to the <a href="https://docs.astuto.io/">Astuto documentation</a>.
|
To customize your feedback space, just head to <a href="<%= get_url_for(method(:site_settings_general_url)) %>">site settings</a>. For more advanced configurations, such as custom OAuth providers or custom domains, you can refer to the <a href="https://github.com/astuto/astuto-docs">Astuto documentation</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
Reference in New Issue
Block a user