Skip to content

Commit

Permalink
V3 customer cases (#682)
Browse files Browse the repository at this point in the history
* created document for customer cases

* add basic structure for customer cases component in web

* retrieve data from sanity studio and add styling module

* current work with retrieving data from shared

* updated loadquery to create new for each studio to be able to fetch data correctly

* add richtextfield to customer case type

* fix linting issue

* Update studio/schemas/documents/specialPages/customerCases.ts

Co-authored-by: Mathias Oterhals Myklebust <[email protected]>

* change to import slug from sanity

* update variablename for customer case

* updated customercases to customercasespage

* added customer cases id to internal pages in link.ts

* change the initial letter to lower case in customercase id

* added ui if zero customer cases

* Update src/customerCases/CustomerCases.tsx

Co-authored-by: Mathias Oterhals Myklebust <[email protected]>

---------

Co-authored-by: Mathias Oterhals Myklebust <[email protected]>
  • Loading branch information
anemne and mathiazom authored Sep 20, 2024
1 parent afae871 commit b7160dc
Show file tree
Hide file tree
Showing 21 changed files with 259 additions and 35 deletions.
38 changes: 31 additions & 7 deletions src/app/(main)/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,27 @@ import CustomErrorMessage from "src/blog/components/customErrorMessage/CustomErr
import { homeLink } from "src/blog/components/utils/linkTypes";
import Compensations from "src/compensations/Compensations";
import CompensationsPreview from "src/compensations/CompensationsPreview";
import CustomerCases from "src/customerCases/CustomerCases";
import CustomerCasesPreview from "src/customerCases/CustomerCasesPreview";
import { getDraftModeInfo } from "src/utils/draftmode";
import SectionRenderer from "src/utils/renderSection";
import { fetchSeoData, generateMetadataFromSeo } from "src/utils/seo";
import { CompanyLocation } from "studio/lib/interfaces/companyDetails";
import { CompensationsPage } from "studio/lib/interfaces/compensations";
import { BlogPage, PageBuilder, Post } from "studio/lib/interfaces/pages";
import { CustomerCasePage } from "studio/lib/interfaces/specialPages";
import { COMPANY_LOCATIONS_QUERY } from "studio/lib/queries/companyDetails";
import {
BLOG_PAGE_QUERY,
POSTS_QUERY,
SEO_SLUG_QUERY,
SLUG_QUERY,
} from "studio/lib/queries/page";
import { COMPENSATIONS_PAGE_QUERY } from "studio/lib/queries/specialPages";
import { loadQuery } from "studio/lib/store";
import {
COMPENSATIONS_PAGE_QUERY,
CUSTOMER_CASES_PAGE_QUERY,
} from "studio/lib/queries/specialPages";
import { loadStudioQuery } from "studio/lib/store";

export const dynamic = "force-dynamic";

Expand Down Expand Up @@ -53,15 +59,25 @@ async function Page({ params }: Props) {
initialBlogPage,
initialCompensationsPage,
initialLocationsData,
initialCustomerCases,
] = await Promise.all([
loadQuery<PageBuilder>(SLUG_QUERY, { slug }, { perspective }),
loadQuery<BlogPage>(BLOG_PAGE_QUERY, { slug }, { perspective }),
loadQuery<CompensationsPage>(
loadStudioQuery<PageBuilder>(SLUG_QUERY, { slug }, { perspective }),
loadStudioQuery<BlogPage>(BLOG_PAGE_QUERY, { slug }, { perspective }),
loadStudioQuery<CompensationsPage>(
COMPENSATIONS_PAGE_QUERY,
{ slug },
{ perspective },
),
loadQuery<CompanyLocation[]>(COMPANY_LOCATIONS_QUERY, {}, { perspective }),
loadStudioQuery<CompanyLocation[]>(
COMPANY_LOCATIONS_QUERY,
{},
{ perspective },
),
loadStudioQuery<CustomerCasePage>(
CUSTOMER_CASES_PAGE_QUERY,
{ slug },
{ perspective },
),
]);

if (initialPage.data) {
Expand All @@ -82,7 +98,7 @@ async function Page({ params }: Props) {
}

if (initialBlogPage.data) {
const initialPosts = await loadQuery<Post[]>(
const initialPosts = await loadStudioQuery<Post[]>(
POSTS_QUERY,
{ slug },
{ perspective },
Expand Down Expand Up @@ -121,6 +137,14 @@ async function Page({ params }: Props) {
);
}

if (initialCustomerCases.data) {
return isDraftMode ? (
<CustomerCasesPreview initialCustomerCases={initialCustomerCases} />
) : (
<CustomerCases customerCasesPage={initialCustomerCases.data} />
);
}

return Page404;
}

Expand Down
20 changes: 14 additions & 6 deletions src/app/(main)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { COMPANY_INFO_QUERY } from "studio/lib/queries/companyDetails";
import { LEGAL_DOCUMENTS_QUERY } from "studio/lib/queries/legalDocuments";
import { NAV_QUERY } from "studio/lib/queries/navigation";
import { SOMEPROFILES_QUERY } from "studio/lib/queries/socialMediaProfiles";
import { loadQuery } from "studio/lib/store";
import { loadStudioQuery } from "studio/lib/store";

import styles from "./layout.module.css";

Expand All @@ -34,11 +34,19 @@ export default async function Layout({
initialLegal,
initialBrandAssets,
] = await Promise.all([
loadQuery<Navigation>(NAV_QUERY, {}, { perspective }),
loadQuery<CompanyInfo>(COMPANY_INFO_QUERY, {}, { perspective }),
loadQuery<SocialMediaProfiles>(SOMEPROFILES_QUERY, {}, { perspective }),
loadQuery<LegalDocument[]>(LEGAL_DOCUMENTS_QUERY, {}, { perspective }),
loadQuery<BrandAssets>(BRAND_ASSETS_QUERY, {}, { perspective }),
loadStudioQuery<Navigation>(NAV_QUERY, {}, { perspective }),
loadStudioQuery<CompanyInfo>(COMPANY_INFO_QUERY, {}, { perspective }),
loadStudioQuery<SocialMediaProfiles>(
SOMEPROFILES_QUERY,
{},
{ perspective },
),
loadStudioQuery<LegalDocument[]>(
LEGAL_DOCUMENTS_QUERY,
{},
{ perspective },
),
loadStudioQuery<BrandAssets>(BRAND_ASSETS_QUERY, {}, { perspective }),
]);

const hasNavData = hasValidData(initialNav.data);
Expand Down
4 changes: 2 additions & 2 deletions src/app/(main)/legal/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import LegalPreview from "src/blog/components/legal/LegalPreview";
import { getDraftModeInfo } from "src/utils/draftmode";
import { LegalDocument } from "studio/lib/interfaces/legalDocuments";
import { LEGAL_DOCUMENT_SLUG_QUERY } from "studio/lib/queries/legalDocuments";
import { loadQuery } from "studio/lib/store";
import { loadStudioQuery } from "studio/lib/store";

export const dynamic = "force-dynamic";

Expand All @@ -19,7 +19,7 @@ async function Page({ params }: Props) {
const { id } = params;
const { perspective, isDraftMode } = getDraftModeInfo();

const initialDocument = await loadQuery<LegalDocument>(
const initialDocument = await loadStudioQuery<LegalDocument>(
LEGAL_DOCUMENT_SLUG_QUERY,
{ slug: id },
{ perspective },
Expand Down
8 changes: 4 additions & 4 deletions src/app/(main)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { LinkType } from "studio/lib/interfaces/navigation";
import { PageBuilder } from "studio/lib/interfaces/pages";
import { LANDING_QUERY } from "studio/lib/queries/navigation";
import { PAGE_QUERY, SEO_PAGE_QUERY } from "studio/lib/queries/page";
import { loadQuery } from "studio/lib/store";
import { loadStudioQuery } from "studio/lib/store";

export async function generateMetadata(): Promise<Metadata> {
const { data: landingId } = await loadQuery<string>(LANDING_QUERY);
const { data: landingId } = await loadStudioQuery<string>(LANDING_QUERY);
const seo = await fetchSeoData(SEO_PAGE_QUERY, { id: landingId });
return generateMetadataFromSeo(seo);
}
Expand All @@ -35,7 +35,7 @@ const pagesLink = {
const Home = async () => {
const { perspective, isDraftMode } = getDraftModeInfo();

const { data: landingId } = await loadQuery<string>(
const { data: landingId } = await loadStudioQuery<string>(
LANDING_QUERY,
{},
{ perspective },
Expand All @@ -53,7 +53,7 @@ const Home = async () => {
);
}

const initialLandingPage = await loadQuery<PageBuilder>(
const initialLandingPage = await loadStudioQuery<PageBuilder>(
PAGE_QUERY,
{ id: landingId },
{ perspective },
Expand Down
4 changes: 2 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { generateMetadataFromSeo } from "src/utils/seo";
import { DefaultLanguageObject } from "studio/lib/interfaces/languages";
import LiveVisualEditing from "studio/lib/loaders/AutomaticVisualEditing";
import { DEFAULT_LANGUAGE_QUERY } from "studio/lib/queries/languages";
import { loadQuery } from "studio/lib/store";
import { loadStudioQuery } from "studio/lib/store";

import "src/styles/global.css";

Expand Down Expand Up @@ -35,7 +35,7 @@ export default async function RootLayout({
let siteLang;

try {
const { data } = await loadQuery<DefaultLanguageObject>(
const { data } = await loadStudioQuery<DefaultLanguageObject>(
DEFAULT_LANGUAGE_QUERY,
);
siteLang = data.defaultLanguage;
Expand Down
18 changes: 17 additions & 1 deletion src/blog/components/utils/linkTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,21 @@ export const studioLink = {
_type: "link",
linkTitle: "Go to studio",
linkType: LinkType.Internal,
internalLink: { _ref: "/studio" },
internalLink: { _ref: "studio" },
};

export const sharedStudioLink = {
_key: "go-to-shared-studio",
_type: "link",
linkTitle: "Go to shared studio",
linkType: LinkType.Internal,
internalLink: { _ref: "shared" },
};

export const sharedCustomerCasesLink = {
_key: "go-to-shared-studio-customer-cases",
_type: "link",
linkTitle: "Go to shared studio",
linkType: LinkType.Internal,
internalLink: { _ref: "shared/structure/customerCases" },
};
49 changes: 49 additions & 0 deletions src/customerCases/CustomerCases.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { sharedCustomerCasesLink } from "src/blog/components/utils/linkTypes";
import LinkButton from "src/components/linkButton/LinkButton";
import { RichText } from "src/components/richText/RichText";
import Text from "src/components/text/Text";
import { getDraftModeInfo } from "src/utils/draftmode";
import { CustomerCasePage } from "studio/lib/interfaces/specialPages";
import { CustomerCase } from "studioShared/lib/interfaces/customerCases";
import { CUSTOMER_CASES_QUERY } from "studioShared/lib/queries/customerCases";
import { loadSharedQuery } from "studioShared/lib/store";

import styles from "./customerCases.module.css";

interface CustomerCasesProps {
customerCasesPage: CustomerCasePage;
}

const CustomerCases = async ({ customerCasesPage }: CustomerCasesProps) => {
const { perspective } = getDraftModeInfo();

const [sharedCustomerCases] = await Promise.all([
loadSharedQuery<CustomerCase[]>(CUSTOMER_CASES_QUERY, {}, { perspective }),
]);

return (
<div className={styles.wrapper}>
<Text type="h1"> {customerCasesPage.basicTitle} </Text>
{sharedCustomerCases && sharedCustomerCases.data.length > 0 ? (
sharedCustomerCases.data.map((customerCase: CustomerCase) => (
<div key={customerCase._id}>
<Text type="h2">{customerCase.basicTitle}</Text>
{customerCase.richText && (
<RichText value={customerCase.richText} />
)}
</div>
))
) : (
<div className={styles.section}>
<Text>
It looks like you haven&apos;t created any customer cases yet.
Please visit the shared studio to add some.
</Text>
<LinkButton link={sharedCustomerCasesLink} />
</div>
)}
</div>
);
};

export default CustomerCases;
31 changes: 31 additions & 0 deletions src/customerCases/CustomerCasesPreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { QueryResponseInitial, useQuery } from "@sanity/react-loader";
import { Suspense } from "react";

import { CustomerCasePage } from "studio/lib/interfaces/specialPages";
import { CUSTOMER_CASES_PAGE_QUERY } from "studio/lib/queries/specialPages";

import CustomerCases from "./CustomerCases";

interface CustomerCasesPreviewProps {
initialCustomerCases: QueryResponseInitial<CustomerCasePage>;
}

const CustomerCasesPreview = ({
initialCustomerCases,
}: CustomerCasesPreviewProps) => {
const { data: customerCases } = useQuery<CustomerCasePage>(
CUSTOMER_CASES_PAGE_QUERY,
{ slug: initialCustomerCases.data.slug.current },
{ initial: initialCustomerCases },
);

return (
customerCases && (
<Suspense>
<CustomerCases customerCasesPage={customerCases} />
</Suspense>
)
);
};

export default CustomerCasesPreview;
12 changes: 12 additions & 0 deletions src/customerCases/customerCases.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.wrapper {
display: flex;
flex-direction: column;
padding: 10rem 5rem;
gap: 5rem;
}

.section {
display: flex;
flex-direction: column;
gap: 5rem;
}
12 changes: 6 additions & 6 deletions src/utils/seo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { DefaultSeo } from "studio/lib/interfaces/defaultSeo";
import { BRAND_ASSETS_QUERY } from "studio/lib/queries/brandAssets";
import { COMPANY_INFO_QUERY } from "studio/lib/queries/companyDetails";
import { DEFAULT_SEO_QUERY } from "studio/lib/queries/seo";
import { loadQuery } from "studio/lib/store";
import { loadStudioQuery } from "studio/lib/store";

type SeoData = {
title: string;
Expand All @@ -36,7 +36,7 @@ export async function fetchSeoData(
variables?: QueryParams | undefined,
): Promise<SeoData | null> {
try {
const { data } = await loadQuery<SeoData>(query, variables);
const { data } = await loadStudioQuery<SeoData>(query, variables);
return data;
} catch (error) {
console.error("Error loading SEO data:", error);
Expand All @@ -49,7 +49,7 @@ export async function fetchPostSeoData(
variables?: QueryParams | undefined,
): Promise<SeoData | null> {
try {
const { data } = await loadQuery<PostSeoData>(query, variables);
const { data } = await loadStudioQuery<PostSeoData>(query, variables);
if (data && data.description) {
const plainTextDescription = toPlainText(data.description);

Expand All @@ -71,13 +71,13 @@ export async function fetchPostSeoData(
export async function generateMetadataFromSeo(
seo: SeoData | null,
): Promise<Metadata> {
const { data: defaultSeo } = await loadQuery<DefaultSeo | null>(
const { data: defaultSeo } = await loadStudioQuery<DefaultSeo | null>(
DEFAULT_SEO_QUERY,
);
const { data: companyInfo } = await loadQuery<CompanyInfo | null>(
const { data: companyInfo } = await loadStudioQuery<CompanyInfo | null>(
COMPANY_INFO_QUERY,
);
const { data: brandAssets } = await loadQuery<BrandAssets | null>(
const { data: brandAssets } = await loadStudioQuery<BrandAssets | null>(
BRAND_ASSETS_QUERY,
);

Expand Down
12 changes: 12 additions & 0 deletions studio/lib/interfaces/specialPages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Slug } from "./global";

export interface CustomerCasePage {
_createdAt: string;
_id: string;
_rev: string;
_type: string;
_updatedAt: string;
basicTitle: string;
page: string;
slug: Slug;
}
3 changes: 3 additions & 0 deletions studio/lib/queries/specialPages.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { groq } from "next-sanity";

export const CUSTOMER_CASES_PAGE_QUERY = groq`
*[_type == "customerCases" && slug.current == $slug][0]`;

export const COMPENSATIONS_PAGE_QUERY = groq`
*[_type == "compensations" && slug.current == $slug][0]
`;
11 changes: 8 additions & 3 deletions studio/lib/store.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import * as queryStore from "@sanity/react-loader";
import { createQueryStore } from "@sanity/react-loader";

import { client } from "./client";
import { token } from "./token";

queryStore.setServerClient(client.withConfig({ token }));
const { loadQuery: loadStudioQuery, setServerClient } = createQueryStore({
client: false,
ssr: true,
});

export const { loadQuery } = queryStore;
setServerClient(client.withConfig({ token }));

export { loadStudioQuery };
Loading

0 comments on commit b7160dc

Please sign in to comment.