Skip to content

Commit

Permalink
Merge pull request #2719 from ever-co/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
evereq authored Jul 13, 2024
2 parents 900eca5 + 4be0660 commit 3b7565a
Show file tree
Hide file tree
Showing 53 changed files with 1,319 additions and 151 deletions.
183 changes: 93 additions & 90 deletions apps/mobile/app.template.json
Original file line number Diff line number Diff line change
@@ -1,91 +1,94 @@
{"name": "$EXPO_PROJECT_SLUG",
"displayName": "$EXPO_PROJECT_NAME",
"expo": {
"name": "$EXPO_PROJECT_NAME",
"slug": "$EXPO_PROJECT_SLUG",
"version": "0.1.0",
"orientation": "portrait",
"icon": "./assets/images/ever-teams-logo.png",
"splash": {
"image": "./assets/images/splash-ever-teams.png",
"resizeMode": "cover",
"backgroundColor": "#ffffff"
},
"owner": "$EXPO_PROJECT_OWNER",
"updates": {
"fallbackToCacheTimeout": 0,
"url": "https://u.expo.dev/$EXPO_PROJECT_ID"
},
"jsEngine": "hermes",
"assetBundlePatterns": ["**/*"],
"plugins": [
[
"expo-media-library",
{
"photosPermission": "Allow $(PRODUCT_NAME) to access your photos.",
"savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos.",
"isAccessMediaLocationEnabled": true
}
],
"sentry-expo",
[
"expo-build-properties",
{
"android": {
"enableProguardInReleaseBuilds": true,
"extraProguardRules": "-keep public class com.horcrux.svg.** {*;}",
"allowBackup": false
}
}
]
],
"android": {
"icon": "./assets/images/app-icon-android-legacy-ever-teams.png",
"package": "ever.team",
"adaptiveIcon": {
"foregroundImage": "./assets/images/app-icon-android-adaptive-foreground-ever.png",
"backgroundImage": "./assets/images/app-icon-android-adaptive-background.png"
},
"splash": {
"image": "./assets/images/splash-ever-teams.png",
"resizeMode": "cover",
"backgroundColor": "#ffffff"
},
"permissions": [
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.ACCESS_MEDIA_LOCATION"
]
},
"ios": {
"icon": "./assets/images/app-icon-ios-ever-teams.png",
"supportsTablet": true,
"bundleIdentifier": "co.ever.teams",
"splash": {
"image": "./assets/images/splash-ever-teams.png",
"tabletImage": "./assets/images/splash-logo-ever-teams-ios-tablet.png",
"resizeMode": "cover",
"backgroundColor": "#ffffff"
},
"infoPlist": {
"NSCameraUsageDescription": "This app uses the camera to scan barcodes on event tickets.",
"NSPhotoLibraryUsageDescription": "Allow $(PRODUCT_NAME) to access your photos.",
"NSPhotoLibraryAddUsageDescription": "Allow $(PRODUCT_NAME) to save photos."
}
},
"web": {
"favicon": "./assets/images/app-icon-web-favicon.png",
"splash": {
"image": "./assets/images/splash-logo-web-ever-teams.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
}
},
"extra": {
"eas": {
"projectId": "$EXPO_PROJECT_ID"
}
},
"runtimeVersion": "exposdk:48.0.0"
}
{
"name": "$EXPO_PROJECT_SLUG",
"displayName": "$EXPO_PROJECT_NAME",
"expo": {
"name": "$EXPO_PROJECT_NAME",
"slug": "$EXPO_PROJECT_SLUG",
"version": "0.1.0",
"orientation": "portrait",
"icon": "./assets/images/ever-teams-logo.png",
"splash": {
"image": "./assets/images/splash-ever-teams.png",
"resizeMode": "cover",
"backgroundColor": "#ffffff"
},
"owner": "$EXPO_PROJECT_OWNER",
"updates": {
"fallbackToCacheTimeout": 0,
"url": "https://u.expo.dev/$EXPO_PROJECT_ID"
},
"jsEngine": "hermes",
"assetBundlePatterns": ["**/*"],
"plugins": [
[
"expo-media-library",
{
"photosPermission": "Allow $(PRODUCT_NAME) to access your photos.",
"savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos.",
"isAccessMediaLocationEnabled": true
}
],
"sentry-expo",
[
"expo-build-properties",
{
"android": {
"enableProguardInReleaseBuilds": true,
"extraProguardRules": "-keep public class com.horcrux.svg.** {*;}",
"allowBackup": false,
"minSdkVersion": 23,
"targetSdkVersion": 34
}
}
]
],
"android": {
"icon": "./assets/images/app-icon-android-legacy-ever-teams.png",
"package": "ever.team",
"adaptiveIcon": {
"foregroundImage": "./assets/images/app-icon-android-adaptive-foreground-ever.png",
"backgroundImage": "./assets/images/app-icon-android-adaptive-background.png"
},
"splash": {
"image": "./assets/images/splash-ever-teams.png",
"resizeMode": "cover",
"backgroundColor": "#ffffff"
},
"permissions": [
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.ACCESS_MEDIA_LOCATION"
]
},
"ios": {
"icon": "./assets/images/app-icon-ios-ever-teams.png",
"supportsTablet": true,
"bundleIdentifier": "co.ever.teams",
"splash": {
"image": "./assets/images/splash-ever-teams.png",
"tabletImage": "./assets/images/splash-logo-ever-teams-ios-tablet.png",
"resizeMode": "cover",
"backgroundColor": "#ffffff"
},
"infoPlist": {
"NSCameraUsageDescription": "This app uses the camera to scan barcodes on event tickets.",
"NSPhotoLibraryUsageDescription": "Allow $(PRODUCT_NAME) to access your photos.",
"NSPhotoLibraryAddUsageDescription": "Allow $(PRODUCT_NAME) to save photos."
}
},
"web": {
"favicon": "./assets/images/app-icon-web-favicon.png",
"splash": {
"image": "./assets/images/splash-logo-web-ever-teams.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
}
},
"extra": {
"eas": {
"projectId": "$EXPO_PROJECT_ID"
}
},
"runtimeVersion": "exposdk:48.0.0"
}
}
6 changes: 3 additions & 3 deletions apps/mobile/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6910,9 +6910,9 @@ fast-levenshtein@^2.0.6:
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==

fast-loops@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/fast-loops/-/fast-loops-1.1.3.tgz#ce96adb86d07e7bf9b4822ab9c6fac9964981f75"
integrity sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==
version "1.1.4"
resolved "https://registry.yarnpkg.com/fast-loops/-/fast-loops-1.1.4.tgz#61bc77d518c0af5073a638c6d9d5c7683f069ce2"
integrity sha512-8dbd3XWoKCTms18ize6JmQF1SFnnfj5s0B7rRry22EofgMu7B6LKHVh+XfFqFGsqnbH54xgeO83PzpKI+ODhlg==

fast-xml-parser@^4.0.12:
version "4.3.2"
Expand Down
65 changes: 65 additions & 0 deletions apps/web/app/[locale]/all-teams/component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use client';

import { useRouter } from 'next/navigation';
import { useRecoilValue } from 'recoil';
import { fullWidthState } from '@app/stores/fullWidth';
import { withAuthentication } from 'lib/app/authenticator';
import { Breadcrumb, Container } from 'lib/components';
import { MainHeader, MainLayout } from 'lib/layout';
import { useOrganizationAndTeamManagers } from '@app/hooks/features/useOrganizationTeamManagers';
import { useEffect } from 'react';
import { useTranslations } from 'next-intl';
import TeamMemberHeader from 'lib/features/team-member-header';
import { IssuesView } from '@app/constants';
import { HeaderTabs } from '@components/pages/all-teams/header-tabs';
import { allTeamsHeaderTabs } from '@app/stores/header-tabs';
import AllTeamsMembers from 'lib/features/all-teams-members';
import { MemberFilter } from 'lib/features/all-teams/all-team-members-filter';

function AllTeamsPage() {
const t = useTranslations();
const fullWidth = useRecoilValue(fullWidthState);
const view = useRecoilValue(allTeamsHeaderTabs);
const { filteredTeams, userManagedTeams } = useOrganizationAndTeamManagers();

const breadcrumb = [
{ title: JSON.parse(t('pages.home.BREADCRUMB')), href: '/' },
{ title: t('common.ALL_TEAMS'), href: '/all-teams' }
];

/* If the user is not a manager in any team or if he's
manager in only one team, then redirect him to the home page
*/
if (userManagedTeams.length < 2) return <RedirectUser />;

return (
<MainLayout className="items-start">
<MainHeader fullWidth={fullWidth} className={'pb-2 pt-10 sticky top-20 z-50'}>
{/* Breadcrumb */}
<div className="flex flex-row items-start justify-between mb-5">
<Breadcrumb paths={breadcrumb} className="text-sm" />
<div className="flex flex-col gap-2 items-end">
<div className="flex h-10 w-max items-center justify-center gap-1">
<HeaderTabs />
</div>
<MemberFilter />
</div>
</div>
<TeamMemberHeader view={IssuesView.CARDS} />
</MainHeader>
<Container fullWidth={fullWidth} className="flex py-10 pt-20">
<AllTeamsMembers teams={filteredTeams} view={view} />
</Container>
</MainLayout>
);
}

function RedirectUser() {
const router = useRouter();
useEffect(() => {
router.push('/');
}, [router]);
return <></>;
}

export default withAuthentication(AllTeamsPage, { displayName: 'AllManagedTeams' });
5 changes: 5 additions & 0 deletions apps/web/app/[locale]/all-teams/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import AllTeamsPage from './component';

export default function Page() {
return <AllTeamsPage />;
}
9 changes: 8 additions & 1 deletion apps/web/app/[locale]/profile/[memberId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export type FilterTab = 'Tasks' | 'Screenshots' | 'Apps' | 'Visited Sites';
const Profile = React.memo(function ProfilePage({ params }: { params: { memberId: string } }) {
const profile = useUserProfilePage();

const [headerSize, setHeaderSize] = useState(10);

const { user } = useAuthenticateUser();
const { isTrackingEnabled, activeTeam, activeTeamManagers } = useOrganizationTeams();
const members = activeTeam?.members;
Expand Down Expand Up @@ -102,7 +104,12 @@ const Profile = React.memo(function ProfilePage({ params }: { params: { memberId
) : (
<MainLayout showTimer={profileIsAuthUser && isTrackingEnabled}>
<ResizablePanelGroup direction="vertical">
<ResizablePanel defaultSize={47} maxSize={50}>
<ResizablePanel
defaultSize={47}
maxSize={50}
className={clsxm(headerSize < 20 ? '!overflow-hidden' : '!overflow-visible')}
onResize={(size) => setHeaderSize(size)}
>
<MainHeader
fullWidth={fullWidth}
className={clsxm(hookFilterType && ['pb-0'], 'pb-2', 'pt-20 sticky top-20 z-50')}
Expand Down
10 changes: 7 additions & 3 deletions apps/web/app/[locale]/settings/team/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { Card } from 'lib/components';

import { DangerZoneTeam, TeamAvatar, TeamSettingForm } from 'lib/settings';

import { useIsMemberManager, useOrganizationTeams } from '@app/hooks';
import { userState } from '@app/stores';
import { useIsMemberManager, useOrganizationTeams, useTeamInvitations } from '@app/hooks';
import { fetchingTeamInvitationsState, userState } from '@app/stores';
import NoTeam from '@components/pages/main/no-team';
import Link from 'next/link';
import { useTranslations } from 'next-intl';
Expand All @@ -26,6 +26,9 @@ const Team = () => {
const [user] = useRecoilState(userState);
const { isTeamMember, activeTeam } = useOrganizationTeams();
const { isTeamManager } = useIsMemberManager(user);
const { teamInvitations } = useTeamInvitations();
const [isFetchingTeamInvitations] = useRecoilState(fetchingTeamInvitationsState);

return (
<div className="overflow-hidden pb-16">
{isTeamMember ? (
Expand All @@ -49,10 +52,11 @@ const Team = () => {
</InteractionObserverVisible>

{/* Invitations */}
{isTeamManager ? (
{isTeamManager && !isFetchingTeamInvitations ? (
<InteractionObserverVisible id="invitations" setActiveSection={setActiveTeam}>
<Accordian
title={t('pages.settingsTeam.INVITATION_HEADING_TITLE')}
defaultOpen={teamInvitations.length ? true : false}
className="w-full max-w-[96vw] p-4 mt-8 dark:bg-dark--theme"
>
<InvitationSetting />
Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/helpers/plan-day-badge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export const planBadgeContent = (plans: IDailyPlan[], taskId: ITeamTask['id']):
if (otherPlansWithTask.length > 0) {
return 'Planned';
} else {
return `Planned ${formatDayPlanDate(plan.date, 'DD MMM YYYY')}`;
return `${formatDayPlanDate(plan.date, 'DD MMM YYYY')}`;
// return `Planned ${formatDayPlanDate(plan.date, 'DD MMM YYYY')}`;
}
// The task does not exist in any plan
} else {
Expand Down
44 changes: 44 additions & 0 deletions apps/web/app/hooks/features/useOrganizationTeamManagers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useRecoilValue } from 'recoil';
import { useAuthenticateUser } from './useAuthenticateUser';
import { useOrganizationTeams } from './useOrganizationTeams';
import { filterValue } from '@app/stores/all-teams';

export function useOrganizationAndTeamManagers() {
const { user } = useAuthenticateUser();
const { teams } = useOrganizationTeams();
const { value: filtered } = useRecoilValue(filterValue);

const userManagedTeams = teams.filter((team) =>
team.members.some((member) => member.employee?.user?.id === user?.id && member.role?.name === 'MANAGER')
);

const filteredTeams =
filtered === 'all'
? userManagedTeams
: filtered === 'pause'
? userManagedTeams.map((team) => ({
...team,
members: team.members.filter((member) => member.timerStatus === 'pause')
}))
: filtered === 'running'
? userManagedTeams.map((team) => ({
...team,
members: team.members.filter((member) => member.timerStatus === 'running')
}))
: filtered === 'suspended'
? userManagedTeams.map((team) => ({
...team,
members: team.members.filter((member) => member.timerStatus === 'suspended')
}))
: filtered === 'invited'
? userManagedTeams.map((team) => ({
...team,
members: team.members.filter((member) => member.employee.acceptDate)
}))
: userManagedTeams;

return {
userManagedTeams,
filteredTeams
};
}
6 changes: 6 additions & 0 deletions apps/web/app/interfaces/IOrganizationTeam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ export interface OT_Role {
isSystem: boolean;
}

export interface ITeamsMembersFilter {
label: string;
value: ITimerStatusEnum | 'all' | 'invited';
bg: string;
}

export enum RoleNameEnum {
SUPER_ADMIN = 'SUPER_ADMIN',
ADMIN = 'ADMIN',
Expand Down
Loading

0 comments on commit 3b7565a

Please sign in to comment.