<commit_before><template>
  <div id="app">
    <div class="weather-card">
      <Search @setAppState="setAppState(...arguments)" ref="search"/>

      <div class="weather" v-if="store.appState.state === 'loaded'"> 
        <Current @changeUnits="fetchWeather()"/>
        <Forecast/>
      </div>

      <div :class="store.appState.state" class="loading-or-error" v-else>
        <span>{{ store.appState.message }}</span>
        <div class="spinner" v-if="store.appState.state === 'loading'"></div>
      </div>

      <button class="refresh" title="Refresh" @click="fetchWeather()" v-if="store.darkRes.currently">
        <IconRefresh/>
        <span>Last updated: {{ store.darkRes.currently.time * 1000 | moment("h:mm A") }}</span>
      </button> 
    </div>
    <Background/>
  </div>
</template>

<script>
import Background from './components/Background'
import Search from './components/Search'
import Current from './components/Current'
import Forecast from './components/Forecast'
import IconRefresh from './assets/icons/ui/refresh.svg'

export default {
  name: 'app',

  components: {
    Background,
    Search,
    Current,
    Forecast,
    IconRefresh
  },

  computed: {
    store () {
      return this.$store.state
    }
  },

  methods: {
    fetchWeather () {
      this.setAppState('loading')
      this.$refs.search.fetchWeather().then(() => {
        this.setAppState('loaded')
      })
    },
    setAppState (state, message) {
      this.store.appState.state = state
      this.store.appState.message = message
    }
  },

  mounted () {
    if (localStorage.units) {
      this.store.units = localStorage.getItem('units')
    }
  }
}
</script>

<style lang="scss">
@import 'scss/_vars.scss';
@import 'scss/_base.scss';
@import 'scss/partials/_spinner.scss';

#app {
  align-items: center;
  display: flex;
  flex-direction: column;
  height: 100%;
  justify-content: center;
}

.weather-card {
  background-color: #fbfbfb;
  border-radius: 3px;
  box-shadow: 0px 0px 150px 0px rgba(0,0,0,0.5);
  color: #96969f;
  display: flex;
  flex-direction: column;
  margin-top: 10vh;
  max-width: 800px;
  min-height: 510px;
  padding: 30px;
  position: relative;
  width: 100%;
  z-index: 1;

  > * {
    display: flex;
    flex-direction: column;
  }
}

.weather {
  flex: 1;
  margin-top: 16px;
  padding-bottom: 16px;
  position: relative;

  .current,
  .forecast {
    animation-duration: 0.3s;
    animation-fill-mode: forwards;
    animation-iteration-count: 1;
    animation-name: fadeIn;
    flex: 1;

    @keyframes fadeIn {
      0% {
        opacity: 0;
      }
      100% {
        opacity: 1;
      }
    }

    svg {
      height: auto;
      width: 100%;
    }
  }
}

.loading-or-error {
  align-items: center;
  flex: 1;
  justify-content: center;
  position: relative;

  .spinner {
    margin: 0 auto;
  }

  span {
    font-size: 16px;
    height: 16px;
    position: absolute;
  }

  &.loading span {
    margin-top: 40px;
  }
}

.refresh {
  align-items: center;
  bottom: 10px;
  flex-direction: row;<commit_msg>Center loading text fix<commit_after><template>
  <div id="app">
    <div class="weather-card">
      <Search @setAppState="setAppState(...arguments)" ref="search"/>

      <div class="weather" v-if="store.appState.state === 'loaded'"> 
        <Current @changeUnits="fetchWeather()"/>
        <Forecast/>
      </div>

      <div :class="store.appState.state" class="loading-or-error" v-else>
        <span>{{ store.appState.message }}</span>
        <div class="spinner" v-if="store.appState.state === 'loading'"></div>
      </div>

      <button class="refresh" title="Refresh" @click="fetchWeather()" v-if="store.darkRes.currently">
        <IconRefresh/>
        <span>Last updated: {{ store.darkRes.currently.time * 1000 | moment("h:mm A") }}</span>
      </button> 
    </div>
    <Background/>
  </div>
</template>

<script>
import Background from './components/Background'
import Search from './components/Search'
import Current from './components/Current'
import Forecast from './components/Forecast'
import IconRefresh from './assets/icons/ui/refresh.svg'

export default {
  name: 'app',

  components: {
    Background,
    Search,
    Current,
    Forecast,
    IconRefresh
  },

  computed: {
    store () {
      return this.$store.state
    }
  },

  methods: {
    fetchWeather () {
      this.setAppState('loading')
      this.$refs.search.fetchWeather().then(() => {
        this.setAppState('loaded')
      })
    },
    setAppState (state, message) {
      this.store.appState.state = state
      this.store.appState.message = message
    }
  },

  mounted () {
    if (localStorage.units) {
      this.store.units = localStorage.getItem('units')
    }
  }
}
</script>

<style lang="scss">
@import 'scss/_vars.scss';
@import 'scss/_base.scss';
@import 'scss/partials/_spinner.scss';

#app {
  align-items: center;
  display: flex;
  flex-direction: column;
  height: 100%;
  justify-content: center;
}

.weather-card {
  background-color: #fbfbfb;
  border-radius: 3px;
  box-shadow: 0px 0px 150px 0px rgba(0,0,0,0.5);
  color: #96969f;
  display: flex;
  flex-direction: column;
  margin-top: 10vh;
  max-width: 800px;
  min-height: 510px;
  padding: 30px;
  position: relative;
  width: 100%;
  z-index: 1;

  > * {
    display: flex;
    flex-direction: column;
  }
}

.weather {
  flex: 1;
  margin-top: 16px;
  padding-bottom: 16px;
  position: relative;

  .current,
  .forecast {
    animation-duration: 0.3s;
    animation-fill-mode: forwards;
    animation-iteration-count: 1;
    animation-name: fadeIn;
    flex: 1;

    @keyframes fadeIn {
      0% {
        opacity: 0;
      }
      100% {
        opacity: 1;
      }
    }

    svg {
      height: auto;
      width: 100%;
    }
  }
}

.loading-or-error {
  align-items: center;
  flex: 1;
  justify-content: center;
  position: relative;

  .spinner {
    margin: 0 auto;
  }

  span {
    font-size: 16px;
    height: 16px;
    position: absolute;
    top: 50%;
  }

  &.loading span {
    margin-top: 40px;
  }
}

.refresh {
  align-items: center;
  bottom: 10px;
  flex-direction: row;
{'fraction_non_alphanumeric': 0.15938009787928223, 'fraction_numerical': 0.021859706362153345, 'mean_word_length': 2.610718492343934, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1242071', 'n_tokens_mistral': 2290, 'n_tokens_neox': 2122, 'n_words': 440}