Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/Expensify/App into feat/#Ex…
Browse files Browse the repository at this point in the history
…pensify#23220-bidirectional-pagination
  • Loading branch information
perunt committed Oct 9, 2023
2 parents 244cff4 + 619aee6 commit 6dd8147
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
---
title: Tax Exempt
description: Tax Exempt
description: Tax-exempt status in Expensify for organizations recognized by the IRS or local tax authorities.
---
## Resource Coming Soon!
# Overview
If your organization is recognized by the IRS or other local tax authorities as tax-exempt, that means you don’t need to pay any tax on your Expensify monthly bill. Please follow these instructions to request tax-exempt status.
# How to request tax-exempt status in Expensify
1. Go to **Settings > Account > Payments**.
1. Click on the option that says **Request Tax-Exempt Status**.
1. After you've requested tax-exempt status, Concierge (our support service) will start a conversation with you. They will ask you to upload a PDF of your tax-exempt documentation. This document should include your VAT number (or "RUT" in Chile). You can use one of the following documents: 501(c), ST-119, or a foreign tax-exempt declaration.
1. Our team will review your document and let you know if we need any more information.
1. Once everything is verified, we'll update your account accordingly.

Once your account is marked as tax-exempt, the corresponding state tax will no longer be applied to future billing.

If you need to remove your tax-exempt status, let your Account Manager know or contact Concierge.

# FAQ
## What happens to my past Expensify bills that incorrectly had tax added to them?
Expensify can provide a refund for the tax you were charged on your previous bills. Please let your Account Manager know or contact Concierge if this is the case.
102 changes: 102 additions & 0 deletions src/components/IFrame.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* eslint-disable es/no-nullish-coalescing-operators */
import React, {useEffect, useState} from 'react';

function getNewDotURL(url) {
const urlObj = new URL(url);
const paramString = urlObj.searchParams.get('param') ?? '';
const pathname = urlObj.pathname.slice(1);

let params;
try {
params = JSON.parse(paramString);
} catch {
params = {};
}

if (pathname === 'inbox') {
return 'home';
}

if (pathname === 'expenses') {
return `${params.viewMode === 'charts' ? 'insights' : 'expenses'}${paramString ? `/?param=${paramString}` : ''}`;
}

if (pathname === 'admin_policies') {
const {section} = params;
return section === 'individual' ? 'individual_workspaces' : 'group_workspaces';
}

if (pathname === 'policy') {
const workspaceID = params.policyID || '';
const section = urlObj.hash.slice(1) || 'overview';

return `workspace/${workspaceID}/${section}`;
}

if (pathname === 'settings') {
const {section} = params;
return `settings/${section}`;
}

if (pathname.includes('domain')) {
return pathname;
}

return pathname;
}

function getOldDotURL(url) {
const urlObj = new URL(url);
const pathname = urlObj.pathname;
const paths = pathname.slice(1).split('/');

if (pathname === 'home') {
return 'inbox';
}

if (pathname === 'expenses' || pathname === 'insights') {
return `expenses/${urlObj.search}`;
}

if (pathname === 'individual_workspaces' || pathname === 'group_workspaces') {
const param = {section: pathname === 'individual_workspaces' ? 'individual' : 'group'};
return `admin_policies?param=${JSON.stringify(param)}`;
}

if (pathname === 'workspace') {
const [, workspaceID, section] = paths;
const param = {policyID: workspaceID};
return `policy/?param${JSON.stringify(param)}#${section}`;
}

if (pathname === 'settings') {
const [, section] = paths;
const param = {section};
return `settings?param=${JSON.stringify(param)}`;
}

return pathname;
}

export default function ReportScreen() {
const [oldDotURL, setOldDotURL] = useState('https://www.expensify.com.dev');

useEffect(() => {
setOldDotURL(`https://expensify.com.dev/${getOldDotURL(window.location.href)}`);

window.addEventListener('message', (event) => {
const url = event.data;
// TODO: use this value to navigate to a new path
// eslint-disable-next-line no-unused-vars
const newDotURL = getNewDotURL(url);
});
}, []);

return (
<iframe
style={{flex: 1}}
src={oldDotURL}
title="OldDot"
/>
);
}
2 changes: 1 addition & 1 deletion src/components/TabSelector/TabSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ const getBackgroundColor = (position, routesLength, tabIndex) => {

function TabSelector({state, navigation, onTabPress, position}) {
const {translate} = useLocalize();

return (
<View style={styles.tabSelector}>
{_.map(state.routes, (route, index) => {
Expand Down Expand Up @@ -120,6 +119,7 @@ function TabSelector({state, navigation, onTabPress, position}) {
activeOpacity={activeOpacity}
inactiveOpacity={inactiveOpacity}
backgroundColor={backgroundColor}
isFocused={isFocused}
/>
);
})}
Expand Down
40 changes: 23 additions & 17 deletions src/components/TabSelector/TabSelectorItem.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Animated} from 'react-native';
import {Animated, StyleSheet} from 'react-native';
import React from 'react';
import PropTypes from 'prop-types';
import styles from '../../styles/styles';
Expand Down Expand Up @@ -27,6 +27,9 @@ const propTypes = {
/** Animated opacity value while the label is in active state */
// eslint-disable-next-line
activeOpacity: PropTypes.any,

/** Whether this tab is active */
isFocused: PropTypes.bool,
};

const defaultProps = {
Expand All @@ -36,29 +39,32 @@ const defaultProps = {
backgroundColor: '',
inactiveOpacity: 1,
activeOpacity: 0,
isFocused: false,
};

const AnimatedPressableWithFeedback = Animated.createAnimatedComponent(PressableWithFeedback);

function TabSelectorItem({icon, title, onPress, backgroundColor, activeOpacity, inactiveOpacity}) {
function TabSelectorItem({icon, title, onPress, backgroundColor, activeOpacity, inactiveOpacity, isFocused}) {
return (
<AnimatedPressableWithFeedback
<PressableWithFeedback
accessibilityLabel={title}
style={[styles.tabSelectorButton, {backgroundColor}]}
style={[styles.tabSelectorButton]}
wrapperStyle={[styles.flex1]}
onPress={onPress}
>
<TabIcon
icon={icon}
activeOpacity={activeOpacity}
inactiveOpacity={inactiveOpacity}
/>
<TabLabel
title={title}
activeOpacity={activeOpacity}
inactiveOpacity={inactiveOpacity}
/>
</AnimatedPressableWithFeedback>
{({hovered}) => (
<Animated.View style={[styles.tabSelectorButton, StyleSheet.absoluteFill, styles.tabBackground(hovered, isFocused, backgroundColor)]}>
<TabIcon
icon={icon}
activeOpacity={styles.tabOpacity(hovered, isFocused, activeOpacity, inactiveOpacity)}
inactiveOpacity={styles.tabOpacity(hovered, isFocused, inactiveOpacity, activeOpacity)}
/>
<TabLabel
title={title}
activeOpacity={styles.tabOpacity(hovered, isFocused, activeOpacity, inactiveOpacity)}
inactiveOpacity={styles.tabOpacity(hovered, isFocused, inactiveOpacity, activeOpacity)}
/>
</Animated.View>
)}
</PressableWithFeedback>
);
}

Expand Down
10 changes: 8 additions & 2 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -3489,11 +3489,17 @@ const styles = (theme) => ({

tabText: (isSelected) => ({
marginLeft: 8,
fontFamily: isSelected ? fontFamily.EXP_NEUE_BOLD : fontFamily.EXP_NEUE,
fontWeight: isSelected ? fontWeightBold : 400,
fontFamily: fontFamily.EXP_NEUE_BOLD,
fontWeight: fontWeightBold,
color: isSelected ? theme.textLight : theme.textSupporting,
}),

tabBackground: (hovered, isFocused, background) => ({
backgroundColor: hovered && !isFocused ? theme.highlightBG : background,
}),

tabOpacity: (hovered, isFocused, activeOpacityValue, inactiveOpacityValue) => (hovered && !isFocused ? inactiveOpacityValue : activeOpacityValue),

/**
* @param {String} backgroundColor
* @param {Number} height
Expand Down

0 comments on commit 6dd8147

Please sign in to comment.